Sfoglia il codice sorgente

fix: inject CWD at runtime, not in system prompt

- CWD moved from system prompt (static) to react_step first-step input (dynamic)
- Each agent session gets the actual working directory at launch time
- Added docs/project-overview.md — comprehensive project summary

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
kenny67nju 5 mesi fa
parent
commit
a269cebc9f
2 ha cambiato i file con 272 aggiunte e 6 eliminazioni
  1. 261 0
      docs/project-overview.md
  2. 11 6
      lambdagent/fromconfig/compiler.py

+ 261 - 0
docs/project-overview.md

@@ -0,0 +1,261 @@
+# LambdagentPaaS 项目整体概况
+
+> 更新日期: 2026-04-04
+
+---
+
+## 1. 项目概况
+
+LambdagentPaaS 是一个基于 **Lambda 演算**理论的 AI Agent 平台,将 Agent 的构建、部署、运行统一在一个 PaaS(Platform as a Service)框架内。
+
+### 核心数据
+
+| 指标 | 数值 |
+|------|------|
+| 代码行数 | ~33,000 行 Python |
+| 核心库 (`lambdagent/`) | 26,318 行,99 个文件 |
+| PaaS 平台 (`agentpaas/`) | 6,806 行,63 个文件 |
+| 内置工具 | 47 个 |
+| LLM Provider | 4 类(Claude Code / Anthropic / OpenAI / Ollama 等) |
+| Agent 示例 | 5 个(agent67, agent67v2, data67, research67, agentbuilder67) |
+| 测试文件 | 21 个 |
+| Git 提交 | 52 个 |
+
+### 核心定位
+
+```
+YAML 配置 → Lambda 演算编译 → ReAct 循环执行 → 工具调用 → 结果返回
+    ↑                                                        ↓
+  PaaS 管理 (版本/租户/计费/追踪)          ← ←  ConversationLam (会话持久化)
+```
+
+---
+
+## 2. 技术路线
+
+### 2.1 理论基础:Lambda 演算同构
+
+项目的独特之处在于将 Agent 构建映射为 Lambda 演算:
+
+| Lambda 构造 | Agent 语义 | 实现 |
+|-------------|-----------|------|
+| λx.body (Lam) | 创建 Agent(prompt → LLM 调用) | `Lam`, `ConversationLam` |
+| f >> g (Compose) | 管道/链式 Agent | `Compose` |
+| Y f (Loop) | ReAct 循环(思考→行动→观察) | `Loop` |
+| If/Route | 条件分支/路由 | `If`, `Route` |
+| Tool | 外部函数(文件/Shell/Git/Web) | `Tool`, `ValidatedTool` |
+| Guard | 输出验证(依赖类型) | `Guard` |
+| Memory | 持久记忆(环境扩展 Γ'=Γ∪store) | `Memory` |
+
+这套理论保证了 Agent 的**可组合性**和**形式化验证**能力。
+
+### 2.2 Provider 统一架构
+
+```
+                    LLMProvider (接口)
+                   chat(messages) → str
+                    /      |       \
+    ClaudeCodeProvider  AnthropicProvider  OpenAICompatProvider
+    (--resume 会话)    (Messages API)    (Ollama/DashScope/DeepSeek/...)
+                    \      |       /
+                   ConversationLam
+                 (messages 历史管理)
+                        |
+                    react_step
+                  (ReAct 循环执行)
+```
+
+### 2.3 PaaS 平台
+
+- **Web 框架**: FastAPI
+- **数据库**: SQLite(开发)/ PostgreSQL(生产)
+- **多租户**: tenant 隔离 + API Key 认证
+- **Agent 生命周期**: create → deploy → chat → update → rollback
+- **版本管理**: 每次 update 创建新版本,支持回滚
+- **执行追踪**: runs 表记录每次执行的输入/输出/耗时/token
+
+### 2.4 YAML 驱动配置
+
+```yaml
+model:
+  provider: claude-code    # 或 anthropic / ollama / dashscope
+  name: sonnet
+  conversation: true       # 启用 ConversationLam
+type: react
+react:
+  maxSteps: 30
+mcp:
+  localTools:
+    - ReadFile
+    - WriteFile
+    - Bash
+    - ...
+```
+
+一份 YAML 定义完整 Agent:模型、工具、循环参数、记忆策略、安全规则。
+
+---
+
+## 3. 优点
+
+### 3.1 理论优雅
+- Lambda 演算同构是同类项目中**独一无二的理论基础**
+- 60/60 Church 编码验证通过,形式化保证
+- 11 个核心构造 + π 演算扩展覆盖所有 Agent 模式
+
+### 3.2 Provider 统一
+- 一套代码支持 7+ LLM 后端(Claude Code / Anthropic / OpenAI / Ollama / DashScope / DeepSeek / Moonshot)
+- 切换模型只改 YAML,代码零改动
+- Claude Code Max Plan 模式**无需 API Key**
+
+### 3.3 会话持久化消除幻觉
+- ConversationLam 维护完整对话历史
+- ClaudeCodeProvider 使用 `--resume` 高效恢复会话
+- 经验证:多步编程任务(读→改→测→提交)**零幻觉**
+
+### 3.4 工具生态丰富
+- 47 个内置工具覆盖:文件操作、Shell、Git、代码搜索、Web、知识库、任务管理、记忆、调度、通知
+- Schema 验证 + 参数别名容错
+- 工具参数文档从 Schema 自动生成
+
+### 3.5 PaaS 完整
+- 多租户、API Key、版本管理、执行追踪、计费
+- SSE 流式输出
+- Feishu(飞书)Bot 集成
+
+---
+
+## 4. 缺点与存在问题
+
+### 4.1 工程鲁棒性不足(对标 Claude Code)
+
+| 维度 | 现状 | 差距 |
+|------|------|------|
+| 流式架构 | 全链路同步阻塞 | 致命 |
+| 并发安全 | Par 是假并行 | 严重 |
+| 取消机制 | 无 | 严重 |
+| 文件隔离 | 所有 Agent 共享 CWD | 严重 |
+| 可观测性 | 基础 print trace | 中等 |
+
+### 4.2 性能瓶颈
+
+- `claude -p` 子进程调用每步 7-40 秒(冷启动 + prompt 处理)
+- 复杂任务需要 20-30 步 × 10s/步 = 3-5 分钟
+- Ollama 32B 模型每步 10-120 秒,上下文窗口仅 32K
+- 无流式输出时用户需要长时间等待
+
+### 4.3 小模型能力不足
+
+- qwen2.5-coder:32b 的指令跟随能力弱于 Claude Sonnet
+- 工具调用 JSON 格式更容易出错
+- 32K 上下文窗口限制多步任务的历史记忆
+- 需要更激进的上下文压缩策略
+
+### 4.4 安全风险
+
+- Shell 工具允许执行任意命令(prompt injection → 命令注入)
+- `dangerousCommandBlock` 仅基于关键词匹配,可被绕过
+- SQLite 单文件数据库无加密
+- API Key 明文存储在 `~/.agentpaas/config.json`
+
+### 4.5 测试覆盖不足
+
+- 21 个测试文件,主要覆盖核心 Lambda 构造
+- Provider、ConversationLam、PaaS API 缺乏系统测试
+- 无集成测试(端到端:YAML → 编译 → 执行 → 验证)
+- 无性能基准测试
+
+---
+
+## 5. 风险评估
+
+| 风险 | 概率 | 影响 | 缓解措施 |
+|------|------|------|----------|
+| Claude Code CLI 接口变更 | 中 | 高(ClaudeCodeProvider 失效) | 抽象层隔离,fallback 到 API |
+| Ollama 模型幻觉 | 高 | 中(小模型指令跟随差) | ConversationLam + 更严格的 prompt |
+| 长时间任务超时 | 中 | 中(用户体验差) | 流式输出 + 进度反馈 |
+| 并发用户冲突 | 低(当前单用户) | 高(文件系统共享) | Git Worktree 隔离 |
+| 安全漏洞(命令注入) | 中 | 高(数据泄露/系统破坏) | ToolGateway + 沙箱化 |
+| 上下文窗口溢出 | 中 | 中(对话截断) | ConversationLam 滑窗压缩 |
+
+---
+
+## 6. 改进方向
+
+### 短期(1-2 周)
+
+1. **Ollama Provider 验证** — 用 ConversationLam + qwen2.5-coder:32b 跑编程任务,验证零幻觉
+2. **流式输出** — 至少在 PaaS chat 层实现 SSE 流式(Claude Code 已有 on_chunk)
+3. **测试覆盖** — 为 Provider、ConversationLam、from_config 添加单元测试
+4. **错误处理** — Provider 级别的重试 + fallback(如 Claude Code 失败降级到 DashScope)
+
+### 中期(1-2 月)
+
+5. **全链路异步化** — `AsyncTerm.apply()` + `async generator` streaming
+6. **文件隔离** — Git Worktree per agent session
+7. **Shell 沙箱** — 命令白名单 + subprocess 隔离
+8. **上下文管理优化** — LLM 辅助摘要压缩(而非简单截断)
+9. **多 Agent 协作** — agent67v2 的 Handoff 机制完善
+
+### 长期(3-6 月)
+
+10. **容器化部署** — Docker + K8s,每个 Agent 运行在独立容器
+11. **可观测性** — OpenTelemetry + 结构化日志 + Grafana 面板
+12. **Agent 市场** — 用户上传/共享 YAML Agent 配置
+13. **LSP 集成** — IDE 内嵌 Agent 能力(类似 Claude Code 的 VS Code 集成)
+14. **形式化验证** — 利用 Lambda 演算基础做 Agent 行为的静态分析
+
+---
+
+## 7. 未来发展方向
+
+### 7.1 "Lambda Agent OS"
+
+将 LambdagentPaaS 发展为一个**操作系统级别的 Agent 平台**:
+
+```
+用户界面层:  CLI / Web UI / IDE Plugin / Bot (飞书/微信)
+   ↓
+Agent 调度层: 任务分配 / 负载均衡 / 优先级队列
+   ↓
+Agent 执行层: ConversationLam + Provider + ReAct Loop
+   ↓
+工具层:      47+ 内置工具 + MCP 扩展 + 自定义工具
+   ↓
+基础设施层:   多模型 (Claude/GPT/Qwen) + 多运行时 (本地/云/边缘)
+```
+
+### 7.2 "YAML 即 Agent"
+
+```yaml
+# 一份 YAML = 一个完整的 AI Agent
+# 从编程助手到数据分析师到客服机器人
+
+agentId: my-custom-agent
+type: react
+model:
+  provider: claude-code
+  name: sonnet
+systemPrompt: |
+  你是...
+mcp:
+  localTools: [ReadFile, Bash, WebSearch]
+```
+
+目标:**任何人都能用 YAML 创建、部署、运行 AI Agent**,不需要写 Python 代码。
+
+### 7.3 理论与工程的桥梁
+
+LambdagentPaaS 的独特价值在于:
+
+- **理论**: Lambda 演算 + π 演算 + 代数效应 = 形式化 Agent 语义
+- **工程**: PaaS + Provider 统一 + ConversationLam = 生产级部署
+- **实践**: 47 个工具 + YAML 配置 = 零代码 Agent 构建
+
+这三者的结合在当前 Agent 框架生态中是**独一无二**的。大多数框架(LangChain, CrewAI, AutoGPT)都是纯工程导向,缺乏理论基础;而纯理论工作又缺乏工程落地。LambdagentPaaS 试图成为两者之间的桥梁。
+
+---
+
+## 8. 一句话总结
+
+**LambdagentPaaS = Lambda 演算的优雅理论 + PaaS 平台的工程实践 + ConversationLam 的零幻觉保证**——一个用 YAML 定义、用 Lambda 编译、用对话驱动的 AI Agent 平台。

+ 11 - 6
lambdagent/fromconfig/compiler.py

@@ -584,10 +584,10 @@ def _compile_react(cfg: Dict, overrides: Dict) -> Term:
       - Early termination on implicit signals
       - Tool call caching
     """
-    # P1: Inject tool parameter docs into system prompt
+    # Inject tool parameter docs into system prompt
+    cfg = dict(cfg)  # shallow copy to avoid mutating original
     tool_docs = _generate_tool_schema_docs(cfg)
     if tool_docs:
-        cfg = dict(cfg)  # shallow copy to avoid mutating original
         cfg["systemPrompt"] = cfg.get("systemPrompt", "") + tool_docs
 
     think = _compile_lam(cfg, "think", overrides=overrides)
@@ -636,9 +636,14 @@ def _compile_react(cfg: Dict, overrides: Dict) -> Term:
         step = _step_counter[0]
         _step_counter[0] += 1
 
-        # Capture original user input on first step
+        # Capture original user input on first step, inject CWD
         if step == 0:
-            _user_input[0] = str(state)
+            cwd = os.getcwd()
+            _user_input[0] = (
+                f"[工作目录] {cwd}\n"
+                f"ReadFile/WriteFile 使用绝对路径(基于上面的工作目录)。\n\n"
+                + str(state)
+            )
 
         # ── Phase 1: Think (beta-reduction) ──
         t0 = time.time()
@@ -654,8 +659,8 @@ def _compile_react(cfg: Dict, overrides: Dict) -> Term:
                 f"注意:工具名是 ReadFile/WriteFile/EditFile/Bash/ListFiles(不是 Read/Write/Edit)。"
             )
         else:
-            # First step or stateless mode: pass full state
-            llm_input = str(state)
+            # First step (with CWD) or stateless mode
+            llm_input = _user_input[0] if step == 0 else str(state)
 
         thought = think.apply(llm_input, ctx)
         think_ms = (time.time() - t0) * 1000