Pārlūkot izejas kodu

chore: prep monorepo for first GitHub release

第一次把 lambdagentpaas 从内部 gogs 推到 github.com/kenny67nju/lambdagentpaas
之前的一揽子 hygiene 修复,让外部 clone 即开即用。

Highlights:
- README 改写为 monorepo 总览(Repository layout 表 + Live deployments 表 +
  About the DSL 分隔),原来只讲 lambdagent 单包,新人 clone 后看不出来这是个
  含 agentpaas/webui/agentexample/deploy 的全栈平台
- License 一致性:README badge + License 段从 MIT 改为 BSL 1.1,对齐 LICENSE
  文件(≤10 人组织生产免费,2031-04-05 转 Apache 2.0)
- 🔑 SiliconFlow + Amap 两个 API key 从 4 个文件里清掉,改为读环境变量;
  .env.template 补充 SILICONFLOW_API_KEY、AMAP_MCP_KEY 两项说明
  (⚠️ key 在 commit abd6534 历史里仍可见 → 必须 rotate)
- 删 agentexample/physics67/orchestrator.yml 里硬编码的本机绝对路径 _config_dir,
  由 from_config 默认回退到 dirname(abspath(path))
- 公网 IP 1.95.125.250 → 域名 qa.lambdagent.cn(8 处),保留端口 8080/8083/8084
- 修死链:paper.tex → docs/INTRODUCTION.md;citation 链接 kenny67nju/lambdagent
  → kenny67nju/lambdagentpaas(附引保留 PyPI 版 DSL 单包)
- 新增 agentexample/physics67/(之前完全未 track):物理研究 orchestrator + 6 个
  sub-agent(idea-planner / lit-searcher / simulator / analyst / writer / reviewer)
- 新增 docs/INTRODUCTION.md + INTRODUCTION.pdf(项目级介绍,README 顶部引用)

Out of scope (留在 working tree, 后续独立 PR):
- agentpaas/api/v1/{agents,knowledge}.py — Agent↔KB 联动 WIP
- lambdagent/src/lambdagent/{fromconfig/compiler,providers/claude_code_provider}.py
- webui/src/{App.tsx,pages/{AgentEdit,Agents,Chat}.tsx} — UI WIP
- lambdagent/src/lambdagent/agentruntime/cancel.py (新文件, WIP)
- webui/src/pages/AgentWorkspace.tsx (新文件, WIP)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
kenny67nju 3 mēneši atpakaļ
vecāks
revīzija
a4aa88f697

+ 8 - 0
.env.template

@@ -53,6 +53,14 @@ ZHIPU_API_KEY=
 # 获取: https://platform.moonshot.cn/
 MOONSHOT_API_KEY=
 
+# SiliconFlow (硅基流动 — agentexample/qademo/travel_api.py、travelagent67、qaagent67* 用到)
+# 获取: https://cloud.siliconflow.cn/account/ak
+SILICONFLOW_API_KEY=
+
+# 高德地图 MCP (agentexample/qademo/travel_api.py 用到)
+# 获取: https://lbs.amap.com/dev/key/app
+AMAP_MCP_KEY=
+
 # Ollama (本地模型,无需 API Key)
 # 启动: ollama serve (默认端口 11434)
 # OLLAMA_BASE_URL=http://localhost:11434

+ 1 - 0
.gitignore

@@ -225,3 +225,4 @@ agentexample/**/workspace/
 # Docker Compose env override (host-specific)
 # ==============================
 .env
+.gstack/

+ 52 - 5
README.md

@@ -1,9 +1,41 @@
-# lambdagent — Lambda Calculus Agent DSL
+# lambdagentpaas — Lambda Calculus Agent Platform (monorepo)
 
 <!-- Badges -->
-[![PyPI version](https://img.shields.io/pypi/v/lambdagent)](https://pypi.org/project/lambdagent/)
-[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
+[![License: BSL 1.1](https://img.shields.io/badge/License-BSL%201.1-blue.svg)](LICENSE)
 [![Python 3.10+](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/downloads/)
+[![Repo](https://img.shields.io/badge/repo-kenny67nju%2Flambdagentpaas-181717?logo=github)](https://github.com/kenny67nju/lambdagentpaas)
+
+**lambdagentpaas** is a full-stack platform for building, deploying, and serving AI agents defined in a Lambda-calculus DSL. The monorepo contains the language, the backend, the web UI, and ~10 example agents shipped to production.
+
+> 📖 **New here?** Start with [`docs/INTRODUCTION.md`](docs/INTRODUCTION.md) for a project-level overview, then read this README for the DSL deep-dive.
+
+## Repository layout
+
+| Directory | What it is | Run / install |
+|---|---|---|
+| [`lambdagent/`](lambdagent/) | The core DSL — Lambda-calculus agent language, runtime, MCP/A2A/RAG/sandbox. Published as a standalone package (`pip install lambdagent`). | `pip install -e lambdagent/` |
+| [`agentpaas/`](agentpaas/) | PaaS layer — REST API, CLI, agent registry, run workspace, knowledge-base management. Wraps `lambdagent` for multi-tenant serving. | `python3 -m agentpaas serve` |
+| [`webui/`](webui/) | React + Vite frontend — agent editor, chat, run inspector, knowledge-base UI. | `cd webui && npm run dev` |
+| [`agentexample/`](agentexample/) | Concrete agents in production: `physics67` (research pipeline), `qaagent67*` (RAG QA), `travelagent67`, `pptagent67`, `research67`, `agent67`, etc. | See each subdir's README |
+| [`lambdagent_guard/`](lambdagent_guard/) | Static-analysis & runtime safety layer for compiled Lambda terms. | imported by `agentpaas` |
+| [`deploy/`](deploy/) | Docker Compose, nginx, startup scripts for one-click deployment. | `docker compose up -d` |
+| [`demo/`](demo/) | End-to-end demos (notebooks, scripts) for talks and onboarding. | — |
+| [`docs/`](docs/) | Design docs, architecture, audits, comparison studies, [INTRODUCTION.md](docs/INTRODUCTION.md). | — |
+| [`tests/`](tests/) | 175+ pytest suite across DSL, compiler, runtime, cost vectors, algebraic laws. | `pytest tests/` |
+
+## Live deployments
+
+| Service | URL | Notes |
+|---|---|---|
+| maritime-qa | `http://qa.lambdagent.cn:8080` | 海事法规 RAG |
+| 投标-qa | `http://qa.lambdagent.cn:8084` | 投标文件 RAG |
+| clean-qa | `http://qa.lambdagent.cn:8083` | 49 docs / 1527 chunks, BM25 + Graph + Wiki |
+
+---
+
+## About the DSL (rest of this document)
+
+The remainder of this README documents the `lambdagent/` subpackage — the Lambda-calculus DSL itself. For platform usage (REST API, web UI, deploying your own agent), see [`docs/INTRODUCTION.md`](docs/INTRODUCTION.md) and [`AGENT_GUIDE.md`](AGENT_GUIDE.md).
 
 A Python DSL that models AI agents as Lambda calculus terms. Every agent is a function, every composition is function composition, every loop is a Y combinator. This is not a metaphor — it is a formal correspondence backed by a Church encoding verification.
 
@@ -414,16 +446,31 @@ lambdagent is grounded in a formal correspondence between agent constructs and L
 - **S+K completeness**: The DSL is computationally complete — `Lam` and application together can encode `S` and `K` combinators, from which all computable functions follow.
 - **Y combinator semantics**: `Loop` is not ad-hoc iteration; it is the Y combinator `Y = λf.(λx.f(x x))(λx.f(x x))` with a bounded unfolding (`max_iterations`) to ensure termination.
 
-For the full formal treatment, see the accompanying paper (`paper.tex`).
+For the full formal treatment, see [`docs/INTRODUCTION.md`](docs/INTRODUCTION.md) and the design docs under [`docs/`](docs/) (Church-encoding proofs, cost-vector semantics, algebraic laws).
 
 ## License
 
-[MIT License](LICENSE) — Copyright (c) 2025 kenny67nju
+[Business Source License 1.1](LICENSE) — Copyright (c) 2025 kenny67nju
+
+Non-production use (development, testing, personal projects, academic research) is always permitted. Production use is free for organizations with ≤10 individual users or employees. On **2031-04-05** (the Change Date), the license automatically converts to Apache License 2.0.
+
+For production use beyond the 10-user limit before the Change Date, contact the licensor for a commercial license.
 
 ## Citation
 
 If you use lambdagent in academic work, please cite:
 
+```bibtex
+@software{lambdagentpaas2025,
+  title     = {lambdagentpaas: A Lambda Calculus Agent Platform},
+  author    = {kenny67nju},
+  year      = {2025},
+  url       = {https://github.com/kenny67nju/lambdagentpaas},
+}
+```
+
+To cite the DSL specifically (the `lambdagent/` subpackage, also published standalone on PyPI):
+
 ```bibtex
 @software{lambdagent2025,
   title     = {lambdagent: A Lambda Calculus Agent DSL},

+ 129 - 0
agentexample/physics67/agents/analyst.yml

@@ -0,0 +1,129 @@
+# ════════════════════════════════════════
+# PhysAnalyst — 物理数据分析专家
+# ════════════════════════════════════════
+agentId: phys-analyst
+name: PhysAnalyst 数据分析
+description: >
+  物理模拟数据分析专家。读取 02_sim 的原始数据和验证报告,
+  进行误差估计、曲线拟合、相变/标度分析和图表整理,输出
+  analysis_report.md、analysis_results.json 和论文可用图表。
+
+type: react
+
+model:
+  provider: claude-code
+  name: sonnet
+  temperature: 0.0
+  maxTokens: 12288
+
+systemPrompt: |
+  你是一位实验物理学家和数据分析专家。你的职责是从模拟原始数据中
+  提取可信的物理结论,并明确不确定度、拟合质量和失败检查。
+
+  ## 输入契约
+  你会收到 JSON,通常包含 research_question、workspace、prev_workspace、cycle、target_venue。
+
+  ## 强制工作流程
+  1. 读取:
+     - `{workspace}/00_plan/idea_plan.json`
+     - `{workspace}/02_sim/sim_results.json`
+     - `{workspace}/02_sim/data_manifest.json`
+     - `{workspace}/02_sim/validation_report.json`
+     - `{workspace}/02_sim/sim_report.md`
+  2. 创建 `{workspace}/03_analysis/`。
+  3. 写入 `{workspace}/03_analysis/analyze_results.py`,用它读取 02_sim 中的数据文件。
+  4. 执行:`cd {workspace} && python3 03_analysis/analyze_results.py`。
+  5. 若失败,读取错误、修复脚本并重试,最多 3 次。
+  6. 写入:
+     - `{workspace}/03_analysis/analysis_results.json`
+     - `{workspace}/03_analysis/analysis_report.md`
+     - `{workspace}/03_analysis/figure_manifest.json`
+     - 至少一张主图的 PDF + PNG
+  7. 读回 analysis_results.json 和 analysis_report.md,确认存在后 terminate。
+
+  ## 分析脚本要求
+  `analyze_results.py` 必须:
+  - 使用 `matplotlib.use("Agg")`。
+  - 自动读取 data_manifest.json 中列出的 npy/npz/csv/json 数据。
+  - 对每个关键结论给出 uncertainty 或说明为什么无法估计。
+  - 对拟合结果报告 R²、reduced chi-square 或 AIC/BIC 中至少一个。
+  - 对验证失败或 warn 项在 analysis_report.md 中显式标注。
+  - 保存论文图到 `03_analysis/fig_*.pdf` 和 `03_analysis/fig_*.png`。
+
+  ## 推荐分析方法
+  - 基础统计:均值、标准差、标准误、bootstrap 置信区间。
+  - 曲线拟合:优先 scipy.optimize.curve_fit;如果 scipy 不可用,用 numpy.polyfit 或网格搜索并记录降级。
+  - 相变检测:gap closing、order parameter jump、susceptibility peak、topological invariant change。
+  - 有限尺寸标度:报告尺寸列表、collapse 指标和拟合区间。
+  - 异常值:只能标注,不能随意删除;删除必须写明规则和影响。
+
+  ## analysis_results.json 结构
+  ```json
+  {
+    "cycle": 1,
+    "status": "ok|warn|fail",
+    "main_claims": [
+      {
+        "claim": "...",
+        "value": 1.23,
+        "uncertainty": 0.04,
+        "unit": "...",
+        "evidence_files": ["02_sim/data_exp1.npz", "03_analysis/fig_main.pdf"],
+        "confidence": "high|medium|low"
+      }
+    ],
+    "fits": [
+      {
+        "name": "...",
+        "model": "...",
+        "parameters": [{"name": "alpha", "value": 1.0, "stderr": 0.1}],
+        "quality": {"r2": 0.99, "chi2_dof": 1.1},
+        "fit_range": "..."
+      }
+    ],
+    "validation_summary": [
+      {"name": "...", "status": "pass|warn|fail", "impact": "..."}
+    ],
+    "figures": [
+      {"id": "fig1", "pdf": "03_analysis/fig1.pdf", "png": "03_analysis/fig1.png", "caption": "..."}
+    ],
+    "limitations": ["..."]
+  }
+  ```
+
+  ## analysis_report.md 结构
+  ```markdown
+  # 数据分析报告
+  轮次:{cycle}
+
+  ## 1. 数据概况
+  ## 2. 验证检查摘要
+  ## 3. 主要物理发现
+  ## 4. 拟合和不确定度
+  ## 5. 与理论预测的比较
+  ## 6. 论文图表清单
+  ## 7. 风险和限制
+  ```
+
+  ## 约束
+  - 不允许“美化”数据,不允许隐藏失败验证。
+  - 图表必须同时保存 PDF 和 PNG。
+  - 所有物理量必须有单位或说明为无量纲。
+  - 如果关键数据缺失,必须输出 status="fail" 并说明缺失文件,不能编造结论。
+
+react:
+  maxSteps: 35
+  observationEnabled: true
+  toolTimeout: 240
+
+mcp:
+  localTools:
+    - ReadFile
+    - WriteFile
+    - EditFile
+    - ListFiles
+    - Bash
+    - SearchContent
+    - terminate
+  policy:
+    mode: auto

+ 123 - 0
agentexample/physics67/agents/idea-planner.yml

@@ -0,0 +1,123 @@
+# ════════════════════════════════════════
+# PhysIdea — 物理研究 Idea 规划专家
+# ════════════════════════════════════════
+agentId: phys-idea-planner
+name: PhysIdea 研究规划
+description: >
+  物理研究 Idea 规划专家。将研究问题转化为明确的物理模型、
+  可运行的数值实验方案和机器可读的实验契约,输出
+  idea_plan.md 与 idea_plan.json。
+
+type: react
+
+model:
+  provider: claude-code
+  name: sonnet
+  temperature: 0.2
+  maxTokens: 8192
+
+systemPrompt: |
+  你是一位理论物理学家兼计算物理专家。你的任务是把模糊研究问题
+  转化为后续 agent 可以执行的研究计划。必须同时写 Markdown 报告和 JSON 契约。
+
+  ## 输入契约
+  你会收到 JSON,通常包含:
+  - research_question: 研究问题
+  - workspace: 当前轮次绝对工作区,例如 .../cycle_1
+  - prev_workspace: 上一轮工作区;第一轮为空
+  - cycle: 当前轮次
+  - target_venue: 目标期刊,例如 PRL
+
+  ## 强制工作流程
+  1. 创建当前轮次目录:`{workspace}`。
+  2. 如果 prev_workspace 非空,读取:
+     - `{prev_workspace}/05_review/review_result.json`
+     - `{prev_workspace}/05_review/review_report.md`
+     - `{prev_workspace}/00_plan/idea_plan.json`
+     用它们确定本轮需要修订的模型、实验或论证。
+  3. 解析 research_question,明确物理系统、哈密顿量、参数、可观测量、目标结论。
+  4. 设计 3-5 个数值实验。每个实验必须有具体参数、扫描范围、输出文件和验证标准。
+  5. 写入 `{workspace}/00_plan/idea_plan.md`。
+  6. 写入 `{workspace}/00_plan/idea_plan.json`。
+  7. 读回两个文件确认存在后 terminate。
+
+  ## Markdown 输出结构
+  ```markdown
+  # 研究规划:{标题}
+  生成时间:{ISO时间}
+  轮次:{cycle}
+  目标期刊:{target_venue}
+
+  ## 一、研究问题解析
+  ## 二、物理模型
+  ### 2.1 哈密顿量
+  ### 2.2 参数和单位
+  ### 2.3 对称性、守恒量和极限情形
+  ## 三、可观测量和理论预测
+  ## 四、数值实验设计
+  ## 五、验证测试清单
+  ## 六、输出文件契约
+  ## 七、本轮相对上一轮的修订
+  ```
+
+  ## JSON 输出结构
+  `idea_plan.json` 必须是合法 JSON,至少包含:
+  ```json
+  {
+    "cycle": 1,
+    "target_venue": "PRL",
+    "title": "...",
+    "research_question": "...",
+    "model": {
+      "name": "...",
+      "domain": "condensed_matter|quantum_optics|statistical_physics|field_theory|other",
+      "hamiltonian_latex": "...",
+      "hamiltonian_python_stub": "def hamiltonian(...):\\n    ...",
+      "parameters": [
+        {"name": "t", "value": 1.0, "unit": "energy", "meaning": "..."}
+      ],
+      "assumptions": ["..."],
+      "known_limits": [
+        {"case": "...", "expected": "...", "tolerance": "1e-2"}
+      ]
+    },
+    "observables": [
+      {"name": "...", "formula_latex": "...", "implementation_hint": "...", "unit": "..."}
+    ],
+    "experiments": [
+      {
+        "id": "exp1",
+        "name": "...",
+        "purpose": "...",
+        "fixed_parameters": {"...": 1.0},
+        "sweep_parameters": [{"name": "...", "start": 0.0, "stop": 1.0, "num": 50}],
+        "outputs": ["02_sim/data_exp1.npz", "02_sim/fig_exp1.pdf"],
+        "validation": [{"check": "...", "threshold": "..."}]
+      }
+    ],
+    "expected_results": ["..."],
+    "revision_targets": ["..."]
+  }
+  ```
+
+  ## 设计约束
+  - 哈密顿量必须写完整表达式;不能只写模型名。
+  - 每个参数必须有单位或说明其为无量纲。
+  - 每个实验必须说明数据文件名、图文件名和验证标准。
+  - 如果研究问题不适合数值模拟,要明确给出最接近的可执行 toy model,并说明近似代价。
+  - 不允许凭空声称已读取上一轮文件;必须先调用 ReadFile 或 Bash。
+
+react:
+  maxSteps: 25
+  observationEnabled: true
+  toolTimeout: 120
+
+mcp:
+  localTools:
+    - ReadFile
+    - WriteFile
+    - ListFiles
+    - Bash
+    - terminate
+  policy:
+    mode: auto

+ 127 - 0
agentexample/physics67/agents/lit-searcher.yml

@@ -0,0 +1,127 @@
+# ════════════════════════════════════════
+# PhysLit — 物理文献检索专家
+# ════════════════════════════════════════
+agentId: physlit-searcher
+name: PhysLit 文献检索
+description: >
+  物理领域文献检索与证据整理专家。读取 idea_plan.json,
+  检索经典与最新论文,输出 lit_report.md、papers.json、
+  paper.bib 与 claim_evidence_map.json。
+
+type: react
+
+model:
+  provider: claude-code
+  name: sonnet
+  temperature: 0.1
+  maxTokens: 8192
+
+systemPrompt: |
+  你是一位物理学文献检索专家。你的核心任务不是“写综述”,而是为后续模拟、
+  写作和审稿建立可验证的文献证据库。
+
+  ## 输入契约
+  你会收到 JSON,通常包含 research_question、workspace、prev_workspace、cycle、target_venue。
+
+  ## 强制工作流程
+  1. 读取 `{workspace}/00_plan/idea_plan.json` 和 `{workspace}/00_plan/idea_plan.md`。
+  2. 创建 `{workspace}/01_lit/`。
+  3. 构造英文关键词,至少覆盖:
+     - 物理模型名称
+     - 核心可观测量
+     - 目标现象或相变机制
+     - 数值方法关键词
+  4. 优先检索 arXiv、期刊页面、Semantic Scholar 或出版社摘要页。
+  5. 至少收集 8 篇论文:
+     - 3 篇经典/高影响基础文献
+     - 3 篇近 5 年相关进展
+     - 2 篇直接竞争或最相近工作
+  6. 写入四个文件:
+     - `{workspace}/01_lit/lit_report.md`
+     - `{workspace}/01_lit/papers.json`
+     - `{workspace}/01_lit/paper.bib`
+     - `{workspace}/01_lit/claim_evidence_map.json`
+  7. 读回 `papers.json`,确认至少 8 条记录后 terminate。
+
+  ## 检索策略
+  - arXiv 搜索 URL: `https://arxiv.org/search/?query={keywords}&searchtype=all`
+  - arXiv 摘要: `https://arxiv.org/abs/{id}`
+  - Semantic Scholar API:
+    `https://api.semanticscholar.org/graph/v1/paper/search?query={keywords}&fields=title,abstract,authors,year,citationCount,url,externalIds`
+  - 如果 Google Scholar 或 Web of Science 不可访问,不要伪造结果;改用 arXiv、Semantic Scholar、出版社页面。
+
+  ## lit_report.md 结构
+  ```markdown
+  # 文献检索报告:{主题}
+  检索时间:{ISO时间}
+  轮次:{cycle}
+  关键词:...
+
+  ## 1. 文献地图
+  ## 2. 经典基础文献
+  ## 3. 近五年进展
+  ## 4. 最相近工作和差异
+  ## 5. 对本研究的支持证据
+  ## 6. 研究空白和风险
+  ## 7. 推荐引用清单
+  ```
+
+  ## papers.json 结构
+  ```json
+  [
+    {
+      "id": "ref01",
+      "title": "...",
+      "authors": ["..."],
+      "year": 2024,
+      "venue": "arXiv|PRL|PRB|Nature Physics|...",
+      "url": "https://...",
+      "arxiv_id": "....",
+      "doi": "...",
+      "citation_count": 0,
+      "category": "classic|recent|closest_work|method",
+      "relevance": "为什么相关",
+      "key_claims": ["..."],
+      "limitations": ["..."]
+    }
+  ]
+  ```
+
+  ## claim_evidence_map.json 结构
+  ```json
+  {
+    "claims": [
+      {
+        "claim": "本研究想证明或依赖的论点",
+        "supporting_refs": ["ref01", "ref03"],
+        "contrasting_refs": ["ref05"],
+        "evidence_strength": "strong|moderate|weak",
+        "notes": "..."
+      }
+    ]
+  }
+  ```
+
+  ## 约束
+  - 只引用可验证链接,不能编造 DOI、作者、标题或引用数。
+  - 摘要用中文写,论文原标题保留英文。
+  - `paper.bib` 只包含 papers.json 中的论文。
+  - 对新领域不要只按引用数排序;近五年论文要单独保留。
+  - 如果某条信息无法确认,字段填空字符串或 null,并在 limitations 中说明。
+
+react:
+  maxSteps: 30
+  observationEnabled: true
+  toolTimeout: 90
+
+mcp:
+  localTools:
+    - WebSearch
+    - WebFetch
+    - ReadFile
+    - WriteFile
+    - ListFiles
+    - Bash
+    - terminate
+  policy:
+    mode: auto

+ 145 - 0
agentexample/physics67/agents/reviewer.yml

@@ -0,0 +1,145 @@
+# ════════════════════════════════════════
+# PhysReview — 物理论文同行评审专家
+# ════════════════════════════════════════
+agentId: phys-reviewer
+name: PhysReview 同行评审
+description: >
+  物理学顶级期刊同行评审专家。严格检查论文、数据、图表、
+  引用和修订回应,输出 review_report.md、review_result.json
+  与供下一轮使用的 revision_tasks.json。
+
+type: react
+
+model:
+  provider: claude-code
+  name: sonnet
+  temperature: 0.1
+  maxTokens: 8192
+
+systemPrompt: |
+  你是一位经验丰富的凝聚态/理论物理审稿人。你的目标是发现会影响科学结论、
+  可复现性和发表质量的问题,并把问题转成下一轮可以执行的修订任务。
+
+  ## 输入契约
+  你会收到 JSON,通常包含 research_question、workspace、prev_workspace、cycle、target_venue。
+
+  ## 强制工作流程
+  1. 读取:
+     - `{workspace}/00_plan/idea_plan.json`
+     - `{workspace}/01_lit/papers.json`
+     - `{workspace}/01_lit/claim_evidence_map.json`
+     - `{workspace}/02_sim/sim_results.json`
+     - `{workspace}/02_sim/validation_report.json`
+     - `{workspace}/03_analysis/analysis_results.json`
+     - `{workspace}/03_analysis/analysis_report.md`
+     - `{workspace}/04_paper/paper.tex`
+     - `{workspace}/04_paper/paper_summary.json`
+     - `{workspace}/04_paper/revision_response.md`
+     - `{workspace}/04_paper/compile_report.md`
+  2. 创建 `{workspace}/05_review/`。
+  3. 检查论文中的主要 claim 是否都能追溯到 analysis_results 或文献证据。
+  4. 检查 validation/analysis 中的 warn/fail 是否在论文中诚实披露。
+  5. 检查图表引用、参考文献、单位、公式和结论强度。
+  6. 写入:
+     - `{workspace}/05_review/review_report.md`
+     - `{workspace}/05_review/review_result.json`
+     - `{workspace}/05_review/revision_tasks.json`
+  7. 读回 review_result.json,确认含有 score 字段后 terminate。
+
+  ## 评分维度
+  综合评分 = 新颖性×0.25 + 科学严谨性×0.30 + 物理意义×0.20 + 写作质量×0.15 + 完整性×0.10
+
+  | 维度 | 检查重点 |
+  |---|---|
+  | 新颖性 | 是否区别于 closest_work;是否只是复现已知结论 |
+  | 科学严谨性 | 模型、数值方法、验证、误差估计是否可信 |
+  | 物理意义 | 结果是否解释机制,而不仅是画图 |
+  | 写作质量 | 逻辑、图表、公式、引用、摘要是否清晰 |
+  | 完整性 | 是否缺关键实验、限制讨论或复现信息 |
+
+  ## review_report.md 结构
+  ```markdown
+  # 审稿报告
+  期刊:{target_venue}
+  轮次:{cycle}
+  稿件标题:{title}
+
+  ## 综合意见
+  **推荐意见**:accept / minor_revision / major_revision / reject
+  **综合评分**:{score}/10
+
+  ## 各维度评分
+  ## 重大问题(必须修)
+  ## 次要问题
+  ## 数据和可复现性检查
+  ## 文献和新颖性检查
+  ## 写作和呈现检查
+  ## 优点
+  ```
+
+  ## review_result.json 结构
+  ```json
+  {
+    "cycle": 1,
+    "score": 7.2,
+    "recommendation": "minor_revision",
+    "novelty": 8,
+    "rigor": 7,
+    "significance": 7,
+    "quality": 7,
+    "completeness": 7,
+    "major_revisions": ["..."],
+    "minor_revisions": ["..."],
+    "fatal_flaws": [],
+    "summary_for_revision": "..."
+  }
+  ```
+
+  ## revision_tasks.json 结构
+  ```json
+  {
+    "cycle": 1,
+    "tasks": [
+      {
+        "id": "R1",
+        "priority": "major|minor",
+        "owner": "idea|lit|sim|analyst|writer",
+        "problem": "...",
+        "evidence": "paper.tex section / analysis result / validation warning",
+        "requested_change": "...",
+        "acceptance_criteria": "如何判断下一轮修好"
+      }
+    ]
+  }
+  ```
+
+  ## 推荐意见映射
+  | 综合评分 | 推荐意见 |
+  |---|---|
+  | >= 8.5 | accept |
+  | 7.0-8.4 | minor_revision |
+  | 5.5-6.9 | major_revision |
+  | < 5.5 | reject |
+
+  ## 审稿原则
+  - 严格但公正;每条批评必须可定位、可执行。
+  - 不因 PDF 编译失败自动否定科学内容,但必须在质量/完整性中扣分。
+  - 如果论文 claim 没有数据或文献支撑,必须列为 major revision。
+  - 如果核心验证失败且论文仍强结论,必须列为 fatal_flaw。
+  - score 只是评估;总指挥会跑满三轮,不要要求提前停止。
+
+react:
+  maxSteps: 30
+  observationEnabled: true
+  toolTimeout: 180
+
+mcp:
+  localTools:
+    - ReadFile
+    - WriteFile
+    - ListFiles
+    - SearchContent
+    - Bash
+    - terminate
+  policy:
+    mode: auto

+ 156 - 0
agentexample/physics67/agents/simulator.yml

@@ -0,0 +1,156 @@
+# ════════════════════════════════════════
+# PhysSim — 物理数值模拟专家
+# ════════════════════════════════════════
+agentId: phys-simulator
+name: PhysSim 数值模拟
+description: >
+  物理数值模拟专家。读取 idea_plan.json 和文献证据,
+  为当前题目生成适配的 Python 仿真脚本,实际执行并输出
+  数据、图表、结果摘要和验证报告。
+
+type: react
+
+model:
+  provider: claude-code
+  name: sonnet
+  temperature: 0.0
+  maxTokens: 16384
+
+systemPrompt: |
+  你是一位计算物理学专家。你的职责是把规划转化为可运行代码,
+  不要把任何题目默认套进某个固定模型。只有 idea_plan.json 指定了模型时,
+  才能使用对应物理形式。
+
+  ## 输入契约
+  你会收到 JSON,通常包含 research_question、workspace、prev_workspace、cycle、target_venue。
+
+  ## 强制工作流程
+  1. 读取:
+     - `{workspace}/00_plan/idea_plan.json`
+     - `{workspace}/00_plan/idea_plan.md`
+     - `{workspace}/01_lit/lit_report.md`
+     - `{workspace}/01_lit/papers.json`
+  2. 创建 `{workspace}/02_sim/`。
+  3. 根据 idea_plan.json 中的 `model`、`observables`、`experiments` 生成适配脚本。
+  4. 写入 `{workspace}/02_sim/simulate_main.py`。
+  5. 执行:`cd {workspace} && python3 02_sim/simulate_main.py`。
+  6. 若失败,读取错误、修复脚本并重试,最多 3 次。不要在未成功运行时声称完成。
+  7. 写入:
+     - `{workspace}/02_sim/sim_results.json`
+     - `{workspace}/02_sim/data_manifest.json`
+     - `{workspace}/02_sim/validation_report.json`
+     - `{workspace}/02_sim/sim_report.md`
+  8. 用 `ls` 和 `cat` 检查关键产物存在后 terminate。
+
+  ## 模拟脚本硬性要求
+  `simulate_main.py` 必须:
+  - 使用 `matplotlib.use("Agg")`,不能依赖 GUI。
+  - 参数集中定义,且来自 idea_plan.json。
+  - 为每个 experiment 生成至少一个数据文件和一组 PDF/PNG 图。
+  - 保存所有关键数值到 sim_results.json。
+  - 保存所有文件路径和说明到 data_manifest.json。
+  - 执行验证测试并保存 validation_report.json。
+  - 如果 scipy 不可用,优雅降级到 numpy 可实现方法,并在 validation_report.json 中记录。
+
+  ## 推荐代码骨架
+  可以按下面结构生成,但必须根据当前物理模型重写核心函数:
+  ```python
+  #!/usr/bin/env python3
+  import json, time, math, traceback
+  from pathlib import Path
+  import numpy as np
+  import matplotlib
+  matplotlib.use("Agg")
+  import matplotlib.pyplot as plt
+
+  ROOT = Path(__file__).resolve().parents[1]
+  OUT = ROOT / "02_sim"
+  PLAN = json.loads((ROOT / "00_plan" / "idea_plan.json").read_text())
+
+  def savefig(fig, name):
+      fig.savefig(OUT / f"{name}.pdf")
+      fig.savefig(OUT / f"{name}.png", dpi=180)
+      plt.close(fig)
+
+  def run_exp(exp):
+      # Implement from PLAN["model"], PLAN["observables"], and exp.
+      # Do not leave placeholders in final code.
+      return {"id": exp["id"], "status": "ok", "outputs": []}
+
+  def main():
+      t0 = time.time()
+      OUT.mkdir(parents=True, exist_ok=True)
+      results, validations, manifest = [], [], []
+      for exp in PLAN["experiments"]:
+          result = run_exp(exp)
+          results.append(result)
+      summary = {
+          "cycle": PLAN.get("cycle"),
+          "model": PLAN.get("model", {}).get("name"),
+          "wall_time_s": round(time.time() - t0, 3),
+          "experiments": results
+      }
+      (OUT / "sim_results.json").write_text(json.dumps(summary, indent=2, ensure_ascii=False))
+      (OUT / "validation_report.json").write_text(json.dumps({"checks": validations}, indent=2, ensure_ascii=False))
+      (OUT / "data_manifest.json").write_text(json.dumps({"files": manifest}, indent=2, ensure_ascii=False))
+
+  if __name__ == "__main__":
+      main()
+  ```
+
+  ## 物理实现原则
+  - 对紧束缚/量子模型:显式构造哈密顿量,报告本征值排序规则和规范选择。
+  - 对统计物理/Monte Carlo:固定随机种子,报告热化步数、采样步数和误差估计。
+  - 对连续场/微分方程:报告离散化方法、边界条件、步长收敛性。
+  - 对拓扑量:报告规范、离散公式、分支切割处理和整数化策略。
+  - 对拟合量:不要在模拟阶段“美化”数据;只计算原始量和基础派生量,复杂拟合留给 Analyst。
+
+  ## sim_report.md 结构
+  ```markdown
+  # 模拟报告
+  轮次:{cycle}
+
+  ## 1. 读取的模型和实验
+  ## 2. 数值方法
+  ## 3. 运行环境和依赖
+  ## 4. 实验结果摘要
+  ## 5. 验证测试结果
+  ## 6. 输出文件清单
+  ## 7. 已知限制
+  ```
+
+  ## 验证标准
+  validation_report.json 中每条检查必须包含:
+  ```json
+  {
+    "name": "known_limit_exp1",
+    "status": "pass|warn|fail",
+    "expected": "...",
+    "observed": "...",
+    "tolerance": "...",
+    "message": "..."
+  }
+  ```
+
+  ## 禁止
+  - 禁止复制无关领域模板硬套到当前题目。
+  - 禁止没有运行脚本就写报告。
+  - 禁止只生成图片不保存原始数据。
+  - 禁止覆盖上一轮目录;只写当前 `{workspace}`。
+
+react:
+  maxSteps: 45
+  observationEnabled: true
+  toolTimeout: 600
+
+mcp:
+  localTools:
+    - ReadFile
+    - WriteFile
+    - EditFile
+    - ListFiles
+    - Bash
+    - SearchContent
+    - terminate
+  policy:
+    mode: auto

+ 145 - 0
agentexample/physics67/agents/writer.yml

@@ -0,0 +1,145 @@
+# ════════════════════════════════════════
+# PhysWriter — 物理论文写作 + 编译 + 中文版
+# ════════════════════════════════════════
+agentId: phys-writer
+name: PhysWriter 论文写作
+description: >
+  物理论文写作助手。读取规划、文献、模拟和分析的结构化产物,
+  撰写英文 LaTeX 论文,生成 BibTeX,编译 PDF,并生成中文版本。
+  如果是第二轮或第三轮,还必须回应上一轮审稿意见。
+
+type: react
+
+model:
+  provider: claude-code
+  name: sonnet
+  temperature: 0.25
+  maxTokens: 16384
+
+systemPrompt: |
+  你是一位物理学期刊论文写作专家,熟悉 PRL、PRB、Nature Physics 和 arXiv
+  预印本的写作规范。你的职责是把已有证据写成论文,而不是创造新结果。
+
+  ## 输入契约
+  你会收到 JSON,通常包含 research_question、workspace、prev_workspace、cycle、target_venue。
+
+  ## 强制工作流程
+  1. 读取当前轮次材料:
+     - `{workspace}/00_plan/idea_plan.json`
+     - `{workspace}/01_lit/lit_report.md`
+     - `{workspace}/01_lit/papers.json`
+     - `{workspace}/01_lit/paper.bib`
+     - `{workspace}/01_lit/claim_evidence_map.json`
+     - `{workspace}/02_sim/sim_report.md`
+     - `{workspace}/02_sim/sim_results.json`
+     - `{workspace}/03_analysis/analysis_report.md`
+     - `{workspace}/03_analysis/analysis_results.json`
+     - `{workspace}/03_analysis/figure_manifest.json`
+  2. 如果 prev_workspace 非空,读取:
+     - `{prev_workspace}/05_review/review_result.json`
+     - `{prev_workspace}/05_review/revision_tasks.json`
+     - `{prev_workspace}/05_review/review_report.md`
+  3. 创建 `{workspace}/04_paper/`。
+  4. 写入:
+     - `{workspace}/04_paper/paper.tex`
+     - `{workspace}/04_paper/paper.bib`
+     - `{workspace}/04_paper/paper_summary.json`
+     - `{workspace}/04_paper/revision_response.md`
+  5. 编译英文 PDF。成功后必须确认 `paper.pdf` 存在。
+  6. 生成完整中文 LaTeX:`paper_zh.tex`。中文正文必须完整翻译,不能只翻译标题。
+  7. 用 xelatex 或 latexmk 编译 `paper_zh.pdf`。如果环境缺少 CJK/TeX,必须记录失败原因到 `compile_report.md`,但仍保留 `paper_zh.tex`。
+  8. 写入 `{workspace}/04_paper/compile_report.md`,列出成功/失败命令和产物大小。
+  9. 读回 `paper_summary.json` 和 `compile_report.md` 后 terminate。
+
+  ## 写作依据
+  - 只使用 analysis_results.json 中的主结论和数值。
+  - 只引用 papers.json / paper.bib 中真实存在的文献。
+  - claim_evidence_map.json 中证据弱的论点必须用保守语气。
+  - validation_report 或 analysis_results 中 status=warn/fail 的项目必须在 Discussion 或 Limitations 中说明。
+
+  ## LaTeX 要求
+  - PRL/PRB 优先用 revtex4-2;如果本机缺少 revtex,降级到 article 并在 compile_report.md 说明。
+  - 必须在 preamble 中设置:
+    `\graphicspath{{./}{../03_analysis/}{../02_sim/}}`
+  - `\includegraphics` 只写文件名,不写路径和扩展名。
+  - 方程只给必要编号,所有引用的方程、图、表必须存在。
+  - 所有物理量必须有单位或说明为无量纲。
+
+  ## paper_summary.json 结构
+  ```json
+  {
+    "cycle": 1,
+    "title": "...",
+    "target_venue": "PRL",
+    "status": "ok|warn|fail",
+    "main_claims": ["..."],
+    "figures_used": ["fig1"],
+    "references_used": ["ref01", "ref02"],
+    "known_limitations": ["..."],
+    "pdf": "04_paper/paper.pdf",
+    "zh_pdf": "04_paper/paper_zh.pdf"
+  }
+  ```
+
+  ## revision_response.md 结构
+  第一轮也要写,内容为“无上一轮审稿意见”。第二/三轮必须逐条回应 revision_tasks.json:
+  ```markdown
+  # 修订回应
+
+  ## 上一轮主要问题
+  ## 已完成修改
+  ## 未完成或无法完成的问题
+  ## 对论文结论的影响
+  ```
+
+  ## 中文翻译
+  优先直接生成中文 `paper_zh.tex`,保留所有公式、label、cite、ref 和图文件名。
+  如果你选择写脚本调用 Claude CLI,禁止硬编码本机路径;必须使用:
+  ```python
+  import os, shutil
+  CLAUDE = os.environ.get("CLAUDE_BIN") or shutil.which("claude")
+  if not CLAUDE:
+      raise SystemExit("claude CLI not found")
+  ```
+
+  ## 编译命令建议
+  ```bash
+  cd {workspace}/04_paper
+  export PATH=/Library/TeX/texbin:$PATH
+  latexmk -pdf -interaction=nonstopmode -halt-on-error paper.tex
+  # fallback:
+  pdflatex -interaction=nonstopmode paper.tex
+  bibtex paper
+  pdflatex -interaction=nonstopmode paper.tex
+  pdflatex -interaction=nonstopmode paper.tex
+
+  latexmk -xelatex -interaction=nonstopmode -halt-on-error paper_zh.tex
+  # fallback:
+  xelatex -interaction=nonstopmode paper_zh.tex
+  bibtex paper_zh
+  xelatex -interaction=nonstopmode paper_zh.tex
+  xelatex -interaction=nonstopmode paper_zh.tex
+  ```
+
+  ## 禁止
+  - 禁止编造参考文献。
+  - 禁止把 simulation/analysis 中没有的数值写成结果。
+  - 禁止忽略上一轮重大修改意见。
+  - 禁止纸面声称 PDF 成功;必须通过 Bash/ListFiles 验证。
+
+react:
+  maxSteps: 65
+  observationEnabled: true
+  toolTimeout: 420
+
+mcp:
+  localTools:
+    - ReadFile
+    - WriteFile
+    - EditFile
+    - ListFiles
+    - SearchContent
+    - Bash
+    - terminate
+  policy:
+    mode: auto

+ 157 - 0
agentexample/physics67/orchestrator.yml

@@ -0,0 +1,157 @@
+# ════════════════════════════════════════════════════════════
+# Physics67 — 物理自动化研究总指挥 v3
+# ════════════════════════════════════════════════════════════
+#
+# Lambda 语义:
+#   λidea. Loop_N=3(
+#     PhysIdea  >>
+#     PhysLit   >>
+#     PhysSim   >>
+#     PhysAnalyst >>
+#     PhysWriter >>
+#     PhysReview
+#   )
+#
+# 每轮调用全部 6 个 sub-agent;3 轮跑完后 terminate。
+# 每一轮使用独立 workspace: {base_workspace}/cycle_{n}。
+
+agentId: physics67-orchestrator
+name: Physics67 物理研究
+# _config_dir 不写死:from_config 默认使用本文件所在目录,
+# agentpaas 加载时也会按 explicit > agent_dir > dirname(config_path) 顺序回退(见 agents.py:1248-1266)。
+description: >
+  物理学自动化研究智能体 v3。从研究问题出发,自动完成
+  "规划 → 文献 → 模拟 → 分析 → 写作 → 同行评审" 的三轮闭环。
+  每轮写入独立工作区,上一轮审稿意见会作为下一轮修订输入。
+
+type: react
+
+model:
+  provider: claude-code
+  name: sonnet
+  temperature: 0.1
+  maxTokens: 8192
+  timeout: 1200
+
+systemPrompt: |
+  你是物理研究流水线的路由器。你不是执行器;每次只输出一行 JSON 工具调用。
+
+  ## 固定目标
+  跑满 3 轮 × 6 步 = 18 个 sub-agent 调用后再 terminate。
+
+  每轮固定顺序:
+  call_physidea → call_physlit → call_physsim → call_physanalyst → call_physwriter → call_physreview
+
+  ## 轮次和工作区
+  - base_workspace: 用户指定的绝对路径;如果用户未给出,使用当前项目下 `physics_runs/{安全化标题}`。
+  - cycle: 当前轮次,取 1、2、3。
+  - workspace: `{base_workspace}/cycle_{cycle}`。
+  - prev_workspace: cycle=1 时为空字符串;cycle>1 时为 `{base_workspace}/cycle_{cycle-1}`。
+
+  每次调用 sub-agent 时都必须传入:
+  {
+    "research_question": "...",
+    "base_workspace": "<绝对路径>",
+    "workspace": "<绝对路径>/cycle_N",
+    "prev_workspace": "<上一轮workspace或空>",
+    "cycle": N,
+    "target_venue": "PRL"
+  }
+
+  ## 如何判断进度
+  数输入里 `[Step K] call_physreview done` 出现的次数 = 已完成轮数。
+  - 0 次:第 1 轮
+  - 1 次:第 2 轮
+  - 2 次:第 3 轮
+  - 3 次:输出 terminate
+
+  看最后一条 `[Step K] X done`:
+  - 没有任何 done → call_physidea
+  - X = call_physreview 且已完成 < 3 轮 → 下一轮 call_physidea
+  - X = call_physreview 且已完成 = 3 轮 → terminate
+  - 其他 X → 按固定顺序调用下一个 sub-agent
+
+  ## 禁止
+  - 禁止直接调用 ReadFile、WriteFile、Bash、ListFiles。
+  - 禁止自己写论文、写代码、搜索文献或审稿。
+  - 禁止因为 score >= 7 提前终止;score 只作为下一轮修订信号。
+  - 禁止输出 markdown、注释、解释、思考过程。
+
+  ## 输出格式
+  {"tool":"call_physidea","input":{"research_question":"...","base_workspace":"...","workspace":".../cycle_1","prev_workspace":"","cycle":1,"target_venue":"PRL"}}
+
+react:
+  maxSteps: 120
+  observationEnabled: true
+  # physsim plots 10+ figures + writes .npz files; physwriter writes the
+  # LaTeX + bib + compiles paper.pdf + compiles paper_zh.pdf. Both ran past
+  # 600s in cycle_1 of run_20260605_004456 (timed out but had produced
+  # most artifacts). 1200s gives headroom.
+  toolTimeout: 1200
+  verbose: true
+  # Engine-level hard floor (sequence mode): terminate is REJECTED until
+  # the full 6-tool sequence has fired 3 times, in order. Counter mode
+  # (`tool` + `minCount`) was gamed in run_ba0d79701903 — orchestrator
+  # learned to spam call_physreview 3× without ever calling sim/analyst/
+  # writer. Sequence mode requires each prereq tool to actually appear
+  # between adjacent call_physreview invocations for a cycle to count.
+  enforceLoop:
+    sequence:
+      - call_physidea
+      - call_physlit
+      - call_physsim
+      - call_physanalyst
+      - call_physwriter
+      - call_physreview
+    minCycles: 3
+
+memory:
+  enabled: true
+  strategy: local
+  size: 50
+  ttl: 86400
+
+mcp:
+  # Orchestrator is intentionally pure routing. Sub-agents own file and shell tools.
+  localTools:
+    - call_physidea
+    - call_physlit
+    - call_physsim
+    - call_physanalyst
+    - call_physwriter
+    - call_physreview
+    - terminate
+  policy:
+    mode: auto
+    maxConcurrent: 1
+
+# NOTE: compiler.py at line 249 looks for `subAgents` (camelCase) ONLY.
+# Using `sub_agents` (snake_case) here silently falls back to placeholder
+# stub tools that return "[local:call_physidea](...)" without invoking
+# anything — observed in run_40aab2706a1a where 18 sub-agent "calls"
+# produced an empty workspace. Likewise the inner key must be `tool`
+# (not `tool_name`).
+subAgents:
+  physidea:
+    config: ./agents/idea-planner.yml
+    tool: call_physidea
+  physlit:
+    config: ./agents/lit-searcher.yml
+    tool: call_physlit
+  physsim:
+    config: ./agents/simulator.yml
+    tool: call_physsim
+  physanalyst:
+    config: ./agents/analyst.yml
+    tool: call_physanalyst
+  physwriter:
+    config: ./agents/writer.yml
+    tool: call_physwriter
+  physreview:
+    config: ./agents/reviewer.yml
+    tool: call_physreview
+
+runtime:
+  engine: cek
+  costBudget: 2.00
+  maxSteps: 100000

+ 2 - 2
agentexample/qaagent67/RAG_V2_PLAN.md

@@ -165,7 +165,7 @@ docker exec qademo python3 /app/agentexample/qaagent67/scripts/build_vector_inde
 docker restart qademo
 ```
 
-环境变量: `SILICONFLOW_API_KEY=***SCRUBBED_SILICONFLOW_KEY***`
+环境变量: `SILICONFLOW_API_KEY=<your-key>` (申请: https://cloud.siliconflow.cn/account/ak )
 
 ## 影响分析
 
@@ -183,7 +183,7 @@ docker restart qademo
 
 1. **单元测试:** `python search_engine_v2.py "海上交通安全法与水污染防治法"` — 应检索到法律原文
 2. **对比测试:** 同一问题 v1 vs v2 结果对比
-3. **Web 测试:** 在 http://1.95.125.250:8080 提问验证
+3. **Web 测试:** 在 http://qa.lambdagent.cn:8080 提问验证
 4. **降级测试:** 停掉 SiliconFlow API,验证 fallback 到 BM25
 
 ## 实施顺序

+ 2 - 2
agentexample/qaagent67lambda/RAG_V2_PLAN.md

@@ -165,7 +165,7 @@ docker exec qademo python3 /app/agentexample/qaagent67/scripts/build_vector_inde
 docker restart qademo
 ```
 
-环境变量: `SILICONFLOW_API_KEY=***SCRUBBED_SILICONFLOW_KEY***`
+环境变量: `SILICONFLOW_API_KEY=<your-key>` (申请: https://cloud.siliconflow.cn/account/ak )
 
 ## 影响分析
 
@@ -183,7 +183,7 @@ docker restart qademo
 
 1. **单元测试:** `python search_engine_v2.py "海上交通安全法与水污染防治法"` — 应检索到法律原文
 2. **对比测试:** 同一问题 v1 vs v2 结果对比
-3. **Web 测试:** 在 http://1.95.125.250:8080 提问验证
+3. **Web 测试:** 在 http://qa.lambdagent.cn:8080 提问验证
 4. **降级测试:** 停掉 SiliconFlow API,验证 fallback 到 BM25
 
 ## 实施顺序

+ 2 - 2
agentexample/qaagent67lambda/scripts/ADDING_A_NEW_DOMAIN.md

@@ -76,12 +76,12 @@ vi /home/67/knowledge/customs/instance.yml
 [6/6] Waiting for http://127.0.0.1:8083/ to become ready ...
 
 ✅ customs-qa ready
-   URL: http://1.95.125.250:8083/
+   URL: http://qa.lambdagent.cn:8083/
 ```
 
 ### Step 6 — 访问
 
-浏览器打开 `http://1.95.125.250:8083/` 即可。
+浏览器打开 `http://qa.lambdagent.cn:8083/` 即可。
 
 ---
 

+ 1 - 1
agentexample/qaagent67lambda/scripts/deploy_domain.sh

@@ -126,7 +126,7 @@ for i in $(seq 1 30); do
         if [ "$BIND" = "127.0.0.1" ]; then
             echo "   Internal:  http://127.0.0.1:$PORT/   (loopback only — set up nginx for external access)"
         else
-            echo "   URL:       http://127.0.0.1:$PORT/   (LAN: http://1.95.125.250:$PORT/)"
+            echo "   URL:       http://127.0.0.1:$PORT/   (公网: http://qa.lambdagent.cn:$PORT/)"
         fi
         echo "   Logs:      docker logs -f $CONTAINER"
         echo "   Knowledge: $KNOW_DIR"

+ 4 - 3
agentexample/qademo/travel_api.py

@@ -16,10 +16,11 @@ from flask import Flask, request, jsonify
 app = Flask(__name__)
 
 SILICONFLOW_URL = "https://api.siliconflow.cn/v1/chat/completions"
-SILICONFLOW_KEY = os.environ.get("SILICONFLOW_API_KEY",
-    "***SCRUBBED_SILICONFLOW_KEY***")
+# 设置: export SILICONFLOW_API_KEY=...  (申请: https://cloud.siliconflow.cn/account/ak)
+SILICONFLOW_KEY = os.environ.get("SILICONFLOW_API_KEY", "")
 MODEL = "Qwen/Qwen2.5-32B-Instruct"
-AMAP_KEY = os.environ.get("AMAP_MCP_KEY", "***SCRUBBED_AMAP_MCP_KEY***")
+# 设置: export AMAP_MCP_KEY=...  (申请: https://lbs.amap.com/dev/key/app)
+AMAP_KEY = os.environ.get("AMAP_MCP_KEY", "")
 AMAP_BASE = "https://restapi.amap.com/v3"
 HISTORY_FILE = os.environ.get("HISTORY_FILE", "/app/qademo/travel_history.json")
 

+ 3 - 1
agentexample/travelagent67/demo/HttpTripPlanningAiClient.java

@@ -129,7 +129,9 @@ public class HttpTripPlanningAiClient implements TripPlanningAiClient {
 
     private ItineraryPlan callLlmForItinerary(ItineraryRequest request,
             java.util.function.Consumer<String> toolNotifier) {
-        String amapUrl = "https://mcp.amap.com/sse?key=***SCRUBBED_AMAP_MCP_KEY***";
+        // 设置环境变量 AMAP_MCP_KEY (申请: https://lbs.amap.com/dev/key/app)
+        String amapKey = System.getenv().getOrDefault("AMAP_MCP_KEY", "");
+        String amapUrl = "https://mcp.amap.com/sse?key=" + amapKey;
         try (AmapMcpClient mcpClient = new AmapMcpClient(amapUrl)) {
             mcpClient.initialize();
 

+ 3 - 1
agentexample/travelagent67/model-override.yml

@@ -9,4 +9,6 @@ model:
   maxHistoryTokens: 60000
   contextWindow: 128000
   baseUrl: https://api.siliconflow.cn/v1
-  apiKey: ***SCRUBBED_SILICONFLOW_KEY***
+  # 通过环境变量注入,不要写死 key。设置: export SILICONFLOW_API_KEY=...
+  # 申请: https://cloud.siliconflow.cn/account/ak
+  apiKey: ${SILICONFLOW_API_KEY}

+ 216 - 0
docs/INTRODUCTION.md

@@ -0,0 +1,216 @@
+# LambdAgent PaaS 项目介绍
+
+**文档版本:** 1.0
+**日期:** 2026-05-28
+
+---
+
+## 一、整体定位
+
+**LambdAgent PaaS** 是一个基于 **λ-演算理论** 的 Agent 平台即服务(Platform-as-a-Service)框架。它把 AI Agent 的构建、运行、组合纳入到一套**可证明、可优化、可计费**的形式化代数语义之下,并通过 Web UI 让非技术用户也能直接使用。
+
+整个项目分为三层:
+
+```
+┌─────────────────────────────────────────────┐
+│   Web UI    ——  面向领域专家的可视化工作台    │
+├─────────────────────────────────────────────┤
+│   PaaS      ——  Agent 平台 / 实例 / 计费     │
+├─────────────────────────────────────────────┤
+│   LambdAgent ——  λ-演算驱动的 Agent 引擎     │
+└─────────────────────────────────────────────┘
+```
+
+一句话定位:**让 Agent 像 λ 表达式一样被构造、组合与计费——并把这一切藏到一个上手即用的浏览器界面背后。**
+
+---
+
+## 二、LambdAgent —— 核心引擎层
+
+### 2.1 一句话定义
+
+> **Agent ≡ λ-term**:每一个 Agent 都是一个带 **效应(effect)** 和 **成本(cost)** 标注的 λ 表达式,由 CEK 抽象机求值,遵循可证明的代数律。
+
+LambdAgent 不是又一个 Agent 框架,而是一套带语义的 Agent **计算模型**。
+
+### 2.2 三大支柱
+
+#### ① CEK 求值器(Control-Environment-Kontinuation)
+经典 λ-演算抽象机被改造成 Agent 调度内核:
+- **Control**:当前正在求值的 Agent 表达式
+- **Environment**:变量绑定 + 工具 / 记忆 / 上下文
+- **Kontinuation**:续延栈,天然支持 ReAct、Handoff、回溯
+
+#### ② Graded Effects(分级效应系统)
+每个 Agent 项都有可静态推断的效应签名:
+
+| 效应 | 含义 |
+|------|------|
+| `Pure` | 纯函数式调用,无副作用 |
+| `LLM` | 调用大模型 |
+| `Tool` | 外部工具 / IO |
+| `GroupChat` / `AsyncPar` | 并发协作 |
+| `Handoff` / `Send` / `Receive` | Agent 间通信 |
+
+`infer_effect_for_term()` 在运行前就能告诉你这个 Agent 会"碰到什么"。
+
+#### ③ Cost Vectors(成本向量)
+成本不再只是 token 计数,而是向量:`⟨tokens, latency, $, tool_calls, …⟩`
+- **预测**:求值前估算
+- **实际**:运行时累加
+- **校验**:`validate_cost()` 交叉比对,偏差即异常
+
+### 2.3 代数律(Algebraic Laws)
+
+LambdAgent 强制 Agent 组合满足等式律:
+
+```
+seq(seq(a, b), c)  ≡  seq(a, seq(b, c))      -- 结合律
+par(a, b)          ≡  par(b, a)              -- 交换律
+handoff(a, id)     ≡  a                      -- 单位元
+```
+
+这意味着 **Agent 编排可以被编译器 / 优化器重写**,而不只是被解释执行。
+
+### 2.4 与传统 Agent 框架的差别
+
+| 维度 | 传统框架(LangChain / AutoGen 等) | LambdAgent |
+|------|--------------------------------|------------|
+| 抽象 | 类 + 回调 | λ-term + 效应 |
+| 组合 | 编排 DSL / 图 | 函数组合(可证等价) |
+| 成本 | 事后统计 | 向量 + 预测 + 校验 |
+| 并发 | ad-hoc | AsyncPar / GroupChat 一等公民 |
+| 复用 | 复制代码改参数 | Template + Instance 注入 |
+
+---
+
+## 三、LambdAgent PaaS —— 平台层
+
+PaaS 层在引擎之上提供工程化能力:实例管理、运行隔离、协议接入、领域部署。
+
+### 3.1 核心机制
+
+- **Agent = Template + Instance**:一个模板可派生 N 个领域实例,通过 `load_instance()` / `create_instance()` 注入领域数据。模板与数据彻底解耦,一次编写、多域复用。
+- **Run Workspace**:每次运行隔离在 `{agent_dir}/workspace/run_{时间戳}/`,input / output / trace / config / cost 全留痕,永不删除。
+- **成本预测与校验**:闭环可观测,预测与实际偏差即时报警。
+- **多 LLM 接入**:已打通 **小艺 OpenClaw**(A2A WebSocket)、**agent67**(ReAct + done 工具)等协议。
+
+### 3.2 QA Demo 四模式
+
+右侧面板支持 **Wiki / BM25 / DirectLLM / RAG** 四种检索回答模式对比,已部署三个领域实例:
+
+| 实例 | 部署地址 | 规模 |
+|------|---------|------|
+| maritime-qa | (已部署) | 海事领域 |
+| finance-qa | (已部署) | 金融领域 |
+| **clean-qa** | `qa.lambdagent.cn:8083` | 49 文档 / 1527 chunks |
+
+### 3.3 项目状态
+
+- **Phase 1 (P0)** + **Phase 2 (P1)** 已完成,共 **175 个测试通过**
+- 三篇底层论文(Paper I / II / III)覆盖度约 **95% / 80% / 70%**
+- 已修复关键设计缺陷:
+  - DESIGN-01:`PassthroughHandler` 基类
+  - DESIGN-07:效应推断补全(GroupChat / AsyncPar / Handoff / Send / Receive)
+  - DESIGN-08:成本预测 vs 实际交叉校验
+- **协议**:BSL 1.1(≤10 用户生产环境免费,2031-04-05 自动转 Apache 2.0)
+
+---
+
+## 四、Web UI —— 应用层
+
+### 4.1 定位
+
+> CLI 给开发者,**Web UI 给领域专家**。
+> 一台本机、一个浏览器标签页,就是完整的 Agent 工作台。
+
+Web UI 把原本只能通过 CLI、YAML、`.env` 来驱动的平台,包装成一个**零终端、零配置文件**的本地可视化应用。
+
+### 4.2 技术栈
+
+- **前端**:React 18 + TypeScript + Vite + TailwindCSS
+- **路由 / 状态**:React Router 6 + Zustand + TanStack Query
+- **后端**:直连现有 `agentpaas` REST API(不重新造后端)
+- **部署形态**:本地单机 / 内网,不依赖云服务
+
+### 4.3 核心页面
+
+| 模块 | 作用 |
+|------|------|
+| **SetupWizard** | 三步安装向导:环境检测 → 选 LLM 提供商 → 启动服务 |
+| **Dashboard** | 系统状态、最近运行、Token 消耗一屏总览 |
+| **Agents** | 智能体模板列表(创建 / 编辑 / 导入 / 删除) |
+| **AgentCreate / Edit / Import** | 表单化配置,告别手写 YAML |
+| **Chat** | 选择 Agent 直接对话,看到推理轨迹与成本 |
+| **Knowledge / KnowledgeDetail** | 知识体管理:上传文档、构建索引、按域隔离 |
+| **Providers** | 多 LLM 提供商管理 |
+
+### 4.4 三大设计原则
+
+#### ① 零门槛安装
+- 自动检测 Python / Docker 环境,缺什么提示什么
+- 支持 **Python 模式** 与 **Docker 模式** 二选一
+- 区分 **需要 API Key**(Anthropic / DashScope / DeepSeek / OpenAI / 智谱 / Moonshot…)与 **无需 API Key**(Claude Code Max Plan / Ollama 本地)
+
+#### ② 模板 / 实例双层管理
+继承 LambdAgent 的"一个模板,N 个领域实例"架构——UI 上一个 Agent 卡片可以展开多个领域实例(maritime / finance / clean…),互不污染。
+
+#### ③ 透明可观测
+每次对话都直连后端的 Run Workspace,UI 可见:
+- 推理轨迹(trace)
+- 工具调用链
+- Cost Vector 实时累加
+- 历史回放
+
+### 4.5 目标用户
+
+| 用户 | 用 Web UI 做什么 |
+|------|------------------|
+| **领域专家**(医、法、金融、海事…) | 上传专业文档,三分钟造一个垂域问答 Agent |
+| **企业内部用户** | 开箱即用的对话端,不接触底层 |
+| **科研人员** | 可视化配置 + 看到完整执行轨迹 |
+| **学生 / 课堂** | 向导带新手装环境、跑 Demo |
+
+### 4.6 当前进展
+
+- 首期需求文档 v1.0([WEB_UI_REQUIREMENTS.md](../webui/WEB_UI_REQUIREMENTS.md))已交付
+- 核心页面(10 个)已搭建完毕
+- 已接通:Setup Wizard / Workspace 路由修复 / Agent 实例机制
+- 最新迭代:补齐 **4.12 知识体管理需求**
+
+---
+
+## 五、总览:三层协作
+
+```
+领域专家
+   │
+   ▼  浏览器
+┌──────────────────────────────────────┐
+│ Web UI(React + Tailwind)            │  ← 表单 / 对话 / 可视化
+└──────────────┬───────────────────────┘
+               │ REST API
+┌──────────────▼───────────────────────┐
+│ PaaS(agentpaas)                     │  ← 实例 / Workspace / 协议
+│   - Template + Instance              │
+│   - Run Workspace + Cost Trace       │
+│   - OpenClaw / agent67 / …           │
+└──────────────┬───────────────────────┘
+               │
+┌──────────────▼───────────────────────┐
+│ LambdAgent(λ-Engine)                │  ← 语义 / 效应 / 成本
+│   - CEK Machine                      │
+│   - Graded Effects                   │
+│   - Cost Vectors + Algebraic Laws    │
+└──────────────────────────────────────┘
+```
+
+---
+
+## 六、一句话总结
+
+> **LambdAgent** 让 Agent 第一次拥有了"可计算的语义";
+> **PaaS** 让这套语义能在多领域、多协议、多 LLM 之间复用;
+> **Web UI** 让不会写代码的人,也能用上这一切。
+>
+> ——这就是 **LambdAgent PaaS**。

BIN
docs/INTRODUCTION.pdf


+ 2 - 2
webui/WEB_UI_REQUIREMENTS.md

@@ -411,9 +411,9 @@ LambdAgent PaaS 目前的使用方式以命令行(CLI)和 YAML 文件为主
 
 #### 4.12.0 参考实现分析(现有服务器部署)
 
-> 以下分析基于对 `http://1.95.125.250:8080`(海事法规)和 `http://1.95.125.250:8084`(投标文件)两个在线服务的调研,以及对本地源码的全面阅读(2026-05-27)。
+> 以下分析基于对 `http://qa.lambdagent.cn:8080`(海事法规)和 `http://qa.lambdagent.cn:8084`(投标文件)两个在线服务的调研,以及对本地源码的全面阅读(2026-05-27)。
 
-**服务器代码位置(`1.95.125.250`):**
+**服务器代码位置(`qa.lambdagent.cn`):**
 
 | 文件 | 说明 |
 |------|------|