chore: import upstream snapshot with attribution
Validate YAML Workflows / Validate YAML Configuration Files (push) Has been cancelled

This commit is contained in:
wehub-resource-sync
2026-07-13 12:37:51 +08:00
commit d0e4308def
614 changed files with 74458 additions and 0 deletions
+141
View File
@@ -0,0 +1,141 @@
# Memory 模块指南
本文档解释 DevAll 的 Memory 体系:memory 列表配置、内置存储实现、Agent 节点如何引用记忆,以及排障建议。代码主要位于 `entity/configs/memory.py``node/agent/memory/*.py`
## 1. 体系结构
1. **Memory Store**:在 YAML `memory[]` 中声明,包含 `name``type``config``type``register_memory_store()` 注册,并映射到具体实现。
2. **Memory Attachment**:在 Agent 节点(`AgentConfig.memories`)中引用 `MemoryAttachmentConfig`,指定读取/写入策略及检索阶段。
3. **MemoryManager**:运行期根据 Attachment+Store 构建 Memory 实例,负责 `load()``retrieve()``update()``save()`
4. **Embedding**`SimpleMemoryConfig``FileMemoryConfig` 可内嵌 `EmbeddingConfig`,由 `EmbeddingFactory` 创建 OpenAI 或本地向量模型。
## 2. Memory 配置示例
```yaml
memory:
- name: convo_cache
type: simple
config:
memory_path: WareHouse/shared/simple.json
embedding:
provider: openai
model: text-embedding-3-small
api_key: ${API_KEY}
- name: project_docs
type: file
config:
index_path: WareHouse/index/project_docs.json
file_sources:
- path: docs/
file_types: [".md", ".mdx"]
recursive: true
embedding:
provider: openai
model: text-embedding-3-small
```
### Mem0 Memory 配置
```yaml
memory:
- name: agent_memory
type: mem0
config:
api_key: ${MEM0_API_KEY}
agent_id: my-agent
```
## 3. 内置 Memory Store 对比
| 类型 | 路径 | 特点 | 适用场景 |
| --- | --- | --- | --- |
| `simple` | `node/agent/memory/simple_memory.py` | 运行结束后可选择落盘(JSON);使用向量搜索(FAISS)+语义重打分;支持读写 | 小规模对话记忆、快速原型 |
| `file` | `node/agent/memory/file_memory.py` | 将指定文件/目录切片为向量索引,只读;自动检测文件变更并更新索引 | 知识库、文档问答 |
| `blackboard` | `node/agent/memory/blackboard_memory.py` | 轻量附加日志,按时间/条数裁剪;不依赖向量检索 | 简易广播板、流水线调试 |
| `mem0` | `node/agent/memory/mem0_memory.py` | 由 Mem0 云端托管;支持语义搜索 + 图关系;无需本地 embedding 或持久化。需安装 `mem0ai` 包。 | 生产级记忆、跨会话持久化、多 Agent 记忆共享 |
> 所有内置 store 都会在 `register_memory_store()` 中注册,摘要可通过 `MemoryStoreConfig.field_specs()` 在 UI 中展示。
## 4. MemoryAttachmentConfig 说明
| 字段 | 说明 |
| --- | --- |
| `name` | 引用的 Memory Store 名称(需在 `stores[]` 中存在且唯一)。|
| `retrieve_stage` | 可选数组,限制检索发生的阶段(`AgentExecFlowStage``pre`, `plan`, `gen`, `critique` 等)。缺省表示所有阶段。|
| `top_k` | 每次检索返回的条数,默认 3。|
| `similarity_threshold` | 过滤相似度下限(-1 表示不限制)。|
| `read` / `write` | 是否允许在该节点读取/写回此记忆。|
Agent 节点示例:
```yaml
nodes:
- id: answer
type: agent
config:
provider: openai
model: gpt-4o-mini
prompt_template: answer_user
memories:
- name: convo_cache
retrieve_stage: ["gen"]
top_k: 5
read: true
write: true
- name: project_docs
read: true
write: false
```
执行顺序:
1. `MemoryManager` 在节点进入 `gen` 阶段时,遍历 Attachments。
2. 满足阶段与 `read=true` 的 Attachment 调用对应 Memory Store 的 `retrieve()`
3. 结果格式化并拼接为“===== 相关记忆 =====”文本写入 Agent 输入上下文。
4. 节点完成后,`write=true` 的 Attachment 将调用 `update()` 并在必要时 `save()`
## 5. Store 细节
所有 Memory Store 都持久化统一的 `MemoryItem` 结构:
- `content_summary`:用于检索的精简文本;
- `input_snapshot` / `output_snapshot`:序列化的消息块(含 base64 附件),确保多模态上下文不会丢失;
- `metadata`:记录角色、输入预览、附件 ID 等附加信息。
这使得 Memory 与 Thinking 模块可以共享多模态内容,无需额外适配。
### 5.1 SimpleMemory
- **路径**`SimpleMemoryConfig.memory_path`(可为 `auto`),缺省仅驻留内存。
- **检索**
1. 以 prompt 构建查询文本并做裁剪。
2. 调用 Embedding 生成向量 → FAISS `IndexFlatIP` 检索 → 语义重打分(Jaccard/LCS)。
- **写入**`update()` 根据输入/输出生成 `MemoryContentSnapshot`,计算摘要哈希去重,再写入 embedding + snapshot + 附件元信息。
- **适配建议**:控制 `max_content_length` 避免爆 context;结合 `top_k`/`similarity_threshold` 防止无关内容。
### 5.2 FileMemory
- **配置**:至少一个 `file_sources`(路径、后缀过滤、递归、编码)。`index_path` 必填,方便增量更新。
- **索引流程**:扫描文件 → 切片(默认 500 字符、重叠 50)→ Embedding → 写入 JSON(包括 `file_metadata`)。
- **检索**:同样使用 FAISS 余弦相似度,只读,不支持 `update()`
- **维护**`load()` 时校验文件哈希,必要时重建索引;建议将 `index_path` 放在持久卷。
### 5.3 BlackboardMemory
- **配置**`memory_path`(可 `auto`)、`max_items`。若路径不存在则在 Session 目录内创建。
- **检索**:直接返回最近 `top_k` 条,按时间排序。
- **写入**`update()` 以 append 方式存储最新的输入/输出 snapshot(文本 + 块 + 附件信息),不生成向量,适合事件流或人工批注。
### 5.4 Mem0Memory
- **配置**:必须提供 `api_key`(从 [app.mem0.ai](https://app.mem0.ai) 获取)。可选参数 `user_id``agent_id``org_id``project_id` 用于记忆范围控制。
- **实体范围**`user_id``agent_id` 是独立的维度,可在 `add()``search()` 调用中同时使用。若同时配置,检索时使用 OR 过滤器(`{"OR": [{"user_id": ...}, {"agent_id": ...}]}`)在一次 API 调用中搜索两个范围。写入时两个 ID 同时包含。
- **检索**:使用 Mem0 服务端语义搜索。通过 `MemoryAttachmentConfig` 中的 `top_k``similarity_threshold` 控制。
- **写入**`update()` 仅将用户输入(`role: "user"` 消息)发送至 Mem0。不包含 Agent 输出,以避免 LLM 响应中的内容被提取为噪声记忆。
- **持久化**:完全由云端托管。`load()``save()` 为空操作(no-op)。记忆在不同运行和会话间自动持久化。
- **依赖**:需安装 `mem0ai` 包(`pip install mem0ai`)。
## 6. EmbeddingConfig 提示
- 字段:`provider`, `model`, `api_key`, `base_url`, `params`
- `provider=openai` 时使用 `openai.OpenAI` 客户端,可配置 `base_url` 以兼容兼容层。
- `params` 支持 `use_chunking`, `chunk_strategy`, `max_length` 等自定义键。
- `provider=local` 时需提供 `params.model_path`,依赖 `sentence-transformers`
## 7. 排错与最佳实践
- **重复命名**:内存列表会校验 `memory[]` 名称唯一;重复时抛出 `ConfigError`
- **缺少 embedding**`SimpleMemory`/`FileMemory` 若未提供 embedding,则仅能以追加方式工作(SimpleMemory)或抛出错误(FileMemory)。
- **权限**:确保 `memory_path`/`index_path` 所在目录可写;容器化部署应挂载卷。
- **性能**
- 大型 FileMemory 建议离线构建索引并缓存。
- 通过 `retrieve_stage` 控制检索次数,减少模型输入冗余。
- 调整 `top_k``similarity_threshold` 以平衡召回与 token 成本。
## 8. 扩展自定义 Memory
1. 新建 Config + Store(继承 `MemoryBase`)。
2.`node/agent/memory/registry.py` 中调用 `register_memory_store("my_store", config_cls=..., factory=..., summary="用途")`
3. 补充 `FIELD_SPECS`,运行 `python -m tools.export_design_template ...` 以让前端获取新枚举。
4. 更新本指南或附带 README,说明新 store 的配置项与边界条件。
+108
View File
@@ -0,0 +1,108 @@
# Thinking 模块指南
Thinking 模块为 Agent 节点提供思考增强能力,使模型能够在生成结果前或后进行额外的推理过程。本文档介绍 Thinking 模块的架构、内置模式及配置方法。
## 1. 体系结构
1. **ThinkingConfig**:在 YAML `nodes[].config.thinking` 中声明,包含 `type``config` 两个字段。
2. **ThinkingManagerBase**:抽象基类,定义 `_before_gen_think``_after_gen_think` 两个时机的思考逻辑。
3. **注册中心**:通过 `register_thinking_mode()` 注册新的思考模式,Schema API 会自动展示可用选项。
## 2. 配置示例
```yaml
nodes:
- id: Thoughtful Agent
type: agent
config:
provider: openai
name: gpt-4o
api_key: ${API_KEY}
thinking:
type: reflection
config:
reflection_prompt: |
请仔细审视你的回答,考虑以下方面:
1. 逻辑是否严密
2. 有无事实错误
3. 表达是否清晰
然后给出改进后的回答。
```
## 3. 内置思考模式
| 类型 | 描述 | 触发时机 | 配置字段 |
|------|------|----------|----------|
| `reflection` | 模型生成后进行自我反思并优化输出 | 生成后 (`after_gen`) | `reflection_prompt` |
### 3.1 Reflection 模式
Self-Reflection 模式让模型在初次生成后对自己的输出进行反思和改进。实现流程:
1. Agent 节点正常调用模型生成初始回答
2. ThinkingManager 将对话历史(系统角色、用户输入、模型输出)拼接为反思上下文
3. 结合 `reflection_prompt` 再次调用模型生成反思结果
4. 反思结果替换原始输出作为节点最终输出
#### 配置项
| 字段 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `reflection_prompt` | string | 是 | 引导模型反思的提示词,可指定反思维度和期望改进方向 |
#### 适用场景
- **写作润色**:让模型自我审阅并修正语法、逻辑问题
- **代码审查**:生成代码后自动进行安全和质量检查
- **复杂推理**:对多步骤推理结果进行验证和修正
## 4. 执行时机
ThinkingManager 支持两种执行时机:
| 时机 | 属性 | 说明 |
|------|------|------|
| 生成前 (`before_gen`) | `before_gen_think_enabled` | 在模型调用前执行思考,可预处理输入 |
| 生成后 (`after_gen`) | `after_gen_think_enabled` | 在模型输出后执行思考,可后处理或优化输出 |
内置的 `reflection` 模式仅启用生成后思考。扩展开发者可根据需求实现生成前思考。
## 5. 与 Memory 的交互
Thinking 模块可访问 Memory 上下文:
- `ThinkingPayload.text`:当前阶段的文本内容
- `ThinkingPayload.blocks`:多模态内容块(图片、附件等)
- `ThinkingPayload.metadata`:附加元数据
Memory 检索结果会通过 `memory` 参数传入思考函数,允许反思时参考历史记忆。
## 6. 扩展自定义思考模式
1. **创建配置类**:继承 `BaseConfig`,定义所需配置字段
2. **实现 ThinkingManager**:继承 `ThinkingManagerBase`,实现 `_before_gen_think``_after_gen_think`
3. **注册模式**
```python
from runtime.node.agent.thinking.registry import register_thinking_mode
register_thinking_mode(
"my_thinking",
config_cls=MyThinkingConfig,
manager_cls=MyThinkingManager,
summary="自定义思考模式描述",
)
```
4. **导出模板**:运行 `python -m tools.export_design_template` 更新前端选项
## 7. 最佳实践
- **控制反思轮次**:当前反思为单轮,若需多轮可在 `reflection_prompt` 中明确迭代要求
- **简洁提示词**:过长的 `reflection_prompt` 会增加 token 消耗,建议聚焦关键改进点
- **配合 Memory**:将重要反思结果存入 Memory,供后续节点参考
- **监控成本**:反思会额外调用模型,注意 token 用量
## 8. 相关文档
- [Agent 节点配置](../nodes/agent.md)
- [Memory 模块](memory.md)
- [工作流编排指南](../workflow_authoring.md)
+47
View File
@@ -0,0 +1,47 @@
# Tooling 模块总览
DevAll 目前支持两类工具绑定到 Agent 节点:
1. **Function Tooling**:调用仓库内的 Python 函数(`functions/function_calling/`),通过 JSON Schema 自动生成工具签名。
2. **MCP Tooling**:连接符合 Model Context Protocol 的外部服务,可直接复用 FastMCP、Claude Desktop 等工具生态。
所有 Tooling 配置都挂载在 `AgentConfig.tooling`
```yaml
nodes:
- id: solve
type: agent
config:
provider: openai
model: gpt-4o-mini
prompt_template: solver
tooling:
type: function
config:
tools:
- name: describe_available_files
- name: load_file
auto_load: true
timeout: 20
```
## 1. 生命周期
1. 解析阶段:`ToolingConfig` 根据 `type` 选择 `FunctionToolConfig``McpRemoteConfig``McpLocalConfig`,字段定义来自 `entity/configs/tooling.py`
2. 运行阶段:Agent 节点根据响应启用工具调用;当 LLM 选择某工具时,执行器会将 `_context`(附件仓库、workspace 路径等)注入函数或通过 MCP 发送请求。
3. 结束阶段:工具输出写入 Agent 消息流,必要时注册为附件(如 `load_file`)。
## 2. 文档结构
- [function.md](function.md)Function Tooling 配置、上下文注入、最佳实践。
- [function_catalog.md](function_catalog.md):仓库内置函数清单与示例。
- [mcp.md](mcp.md):MCP 工具配置、自动启动、FastMCP 示例、安全提示。
## 3. 快速对比
| 维度 | Function | MCP |
| --- | --- | --- |
| 部署 | 同进程调用本地 Python 函数 | Remote:直连 HTTP 服务;Local:拉起本地进程并通过 stdio 连接 |
| Schemas | 自动从类型注解 + `ParamMeta` 生成 | 由 MCP JSON Schema 提供 |
| 上下文 | 自动注入 `_context`(附件/workspace | 取决于 MCP 服务器实现 |
| 典型用途 | 文件操作、本地脚本、内部 API | 第三方工具合集、浏览器、数据库代理 |
## 4. 安全提示
- Function Tooling 运行在后端进程中,应确保函数遵循最小权限原则;不要在函数中执行不受控的命令。
- MCP Tooling 分为 **Remote (HTTP)****Local (stdio)**。Remote 仅配置已有服务器地址;Local 会拉起进程,请使用受控脚本并限制环境变量,必要时通过 `wait_for_log` 等字段判断进程是否就绪。
- 若工具可能修改附件或 workspace,请结合 [附件指南](../../attachments.md) 了解生命周期与清理策略。
+80
View File
@@ -0,0 +1,80 @@
# Function Tooling 配置指南
`FunctionToolConfig` 允许 Agent 节点调用仓库中的 Python 函数。相关代码位于 `entity/configs/tooling.py``utils/function_catalog.py` 以及 `functions/function_calling/`
## 1. 配置字段
| 字段 | 说明 |
| --- | --- |
| `tools` | 列表,元素为 `FunctionToolEntryConfig`。每个条目至少包含 `name`。|
| `timeout` | 单次工具执行的超时时间(秒)。|
`FunctionToolEntryConfig` 字段:
- `name`:函数名,来自 `functions/function_calling/` 文件的顶级函数。
### 函数列表展示与 `module_name:All`
- UI 下拉列表会将每个函数展示为 `module_name:function_name``module_name` 等于函数文件相对于 `functions/function_calling/` 的路径(去掉 `.py`,子目录使用 `/` 连接),便于快速定位语义相关模块。
- 每个模块顶部都会自动插入 `module_name:All` 选项,并且所有模块的 `All` 条目按照字典序排在列表最前。选择该项时会在解析阶段展开为该模块下的所有函数,顺序同样遵循字典序。
- `module_name:All` 只能批量引入函数,禁止同时填写 `description``parameters``auto_fill` 等覆盖字段;若需要自定义,请展开后针对具体函数单独配置。
- 函数与模块都采用全局字典序排列,使长列表更易检索;YAML 中仍然以真实函数名落盘,`module_name:All` 仅作为输入辅助。
## 2. 函数目录要求
- 路径:`functions/function_calling/`(可通过 `MAC_FUNCTIONS_DIR` 覆盖)。
- 每个函数:
- 必须位于模块顶层。
- 使用 Python 类型注解;若需枚举或描述,可使用 `typing.Annotated[..., ParamMeta(...)]`
- 不允许以 `_` 开头的参数暴露给 Agent`*_args``**kwargs` 会被过滤。
- 可以通过 docstring 的首段提供描述(自动截断为 600 字符)。
- `utils/function_catalog.py` 会在启动时生成 JSON Schema,并向前端/CLI 暴露。
## 3. 上下文注入
执行器会对被调用的函数提供 `_context` 关键字参数,包含:
| 键 | 值 |
| --- | --- |
| `attachment_store` | `utils.attachments.AttachmentStore` 实例,可查询/注册附件。|
| `python_workspace_root` | 当前 Session 的 `code_workspace/`。|
| `graph_directory` | Session 根目录,可推导相对路径。|
| `human_prompt` | `utils.human_prompt.HumanPromptService`,可调用 `request()` 触发人工反馈。|
| 其他 | 视运行环境扩展,例如 `session_id``node_id`。|
函数可声明 `_context: dict | None = None` 并自行解析(参考 `functions/function_calling/file.py` 中的 `FileToolContext`,还可参考 `functions/function_calling/user.py`)。
## 4. 示例:文件读取工具
```python
from typing import Annotated
from utils.function_catalog import ParamMeta
def read_text_file(
path: Annotated[str, ParamMeta(description="workspace 相对路径")],
*,
encoding: str = "utf-8",
_context: dict | None = None,
) -> str:
ctx = FileToolContext(_context)
target = ctx.resolve_under_workspace(path)
return target.read_text(encoding=encoding)
```
在 YAML 中引用:
```yaml
nodes:
- id: summarize
type: agent
config:
tooling:
type: function
config:
tools:
- name: describe_available_files
- name: read_text_file
```
## 5. 扩展流程
1.`functions/function_calling/` 新建模块或函数。
2. 使用类型注解 + `ParamMeta` 描述参数;如需禁止自动 Schema,可设置 `auto_fill: false` 并提供手写 `parameters`
3. 若函数依赖额外第三方库,可在仓库 `requirements.txt`/`pyproject.toml` 中声明,或在函数内调用 `install_python_packages`(同目录提供)动态安装。
4. 运行 `python -m tools.export_design_template ...` 以刷新前端枚举。
## 6. 调试与排错
- 若前端/CLI 报告 “function 'xxx' not found”,检查函数名称与文件是否位于 `MAC_FUNCTIONS_DIR`(默认 `functions/function_calling/`)。
- `function_catalog` 加载失败时,`FunctionToolEntryConfig.field_specs()` 会在描述中提示错误,请先修复函数语法或依赖。
- 工具运行超时会向 Agent 返回异常文本;可通过 `timeout` 扩大限额,或在函数内部自行捕获并返回友好错误。
+168
View File
@@ -0,0 +1,168 @@
# 内置 Function 工具目录
本文档列出 `functions/function_calling/` 目录中预置的所有工具,供 Agent 节点通过 Function Tooling 调用。
## 快速导入
在 YAML 中可通过以下方式引用:
```yaml
tooling:
- type: function
config:
tools:
- name: file:All # 导入整个模块
- name: save_file # 导入单个函数
- name: deep_research:All
```
---
## 文件操作 (file.py)
文件与目录操作工具集,用于在 `code_workspace/` 中进行文件管理。
| 函数 | 说明 |
|------|------|
| `describe_available_files` | 列出附件仓库和 code_workspace 中的可用文件 |
| `list_directory` | 列出指定目录内容 |
| `create_folder` | 创建文件夹(支持多级目录) |
| `delete_path` | 删除文件或目录 |
| `load_file` | 加载文件并注册为附件,支持多模态(文本/图片/音频) |
| `save_file` | 保存文本内容到文件 |
| `read_text_file_snippet` | 读取文本片段(offset + limit),适合大文件 |
| `read_file_segment` | 按行范围读取文件,支持行号元数据 |
| `apply_text_edits` | 应用多处文本编辑,保留换行符和编码 |
| `rename_path` | 重命名文件或目录 |
| `copy_path` | 复制文件或目录树 |
| `move_path` | 移动文件或目录 |
| `search_in_files` | 在工作区文件中搜索文本或正则模式 |
**示例 YAML**[ChatDev_v1.yaml](../../../../../yaml_instance/ChatDev_v1.yaml)、[file_tool_use_case.yaml](../../../../../yaml_instance/file_tool_use_case.yaml)
---
## Python 环境管理 (uv_related.py)
使用 uv 管理 Python 环境和依赖。
| 函数 | 说明 |
|------|------|
| `install_python_packages` | 使用 `uv add` 安装 Python 包 |
| `init_python_env` | 初始化 Python 环境(uv lock + venv |
| `uv_run` | 在工作区内执行 uv run,运行模块或脚本 |
**示例 YAML**[ChatDev_v1.yaml](../../../../../yaml_instance/ChatDev_v1.yaml)
---
## 深度研究 (deep_research.py)
搜索结果管理与报告生成工具,适用于自动化研究场景。
### 搜索结果管理
| 函数 | 说明 |
|------|------|
| `search_save_result` | 保存或更新搜索结果(URL、标题、摘要、详情) |
| `search_load_all` | 加载所有已保存的搜索结果 |
| `search_load_by_url` | 按 URL 加载特定搜索结果 |
| `search_high_light_key` | 为搜索结果保存高亮关键词 |
### 报告管理
| 函数 | 说明 |
|------|------|
| `report_read` | 读取报告完整内容 |
| `report_read_chapter` | 读取特定章节(支持多级路径如 `Intro/Background` |
| `report_outline` | 获取报告大纲(标题层级结构) |
| `report_create_chapter` | 创建新章节 |
| `report_rewrite_chapter` | 重写章节内容 |
| `report_continue_chapter` | 追加内容到现有章节 |
| `report_reorder_chapters` | 重新排序章节 |
| `report_del_chapter` | 删除章节 |
| `report_export_pdf` | 导出报告为 PDF |
**示例 YAML**[deep_research_v1.yaml](../../../../../yaml_instance/deep_research_v1.yaml)
---
## 网络工具 (web.py)
网络搜索与网页内容获取。
| 函数 | 说明 |
|------|------|
| `web_search` | 使用 Serper.dev 执行网络搜索,支持分页和多语言 |
| `read_webpage_content` | 使用 Jina Reader 读取网页内容,支持速率限制 |
**环境变量**
- `SERPER_DEV_API_KEY`Serper.dev API 密钥
- `JINA_API_KEY`:Jina API 密钥(可选,无密钥时自动限速 20 RPM)
**示例 YAML**[deep_research_v1.yaml](../../../../../yaml_instance/deep_research_v1.yaml)
---
## 视频工具 (video.py)
Manim 动画渲染与视频处理。
| 函数 | 说明 |
|------|------|
| `render_manim` | 渲染 Manim 脚本,自动检测场景类并输出视频 |
| `concat_videos` | 使用 FFmpeg 拼接多个视频文件 |
**示例 YAML**[teach_video.yaml](../../../../../yaml_instance/teach_video.yaml)、[teach_video.yaml](../../../../../yaml_instance/teach_video.yaml)
---
## 代码执行 (code_executor.py)
| 函数 | 说明 |
|------|------|
| `execute_code` | 执行 Python 代码字符串,返回 stdout 和 stderr |
> ⚠️ **安全提示**:此工具具有高权限,应仅在可信工作流内使用。
---
## 用户交互 (user.py)
| 函数 | 说明 |
|------|------|
| `call_user` | 向用户发送指令并获取响应,用于需要人工输入的场景 |
---
## 天气查询 (weather.py)
示例工具,用于演示 Function Calling 流程。
| 函数 | 说明 |
|------|------|
| `get_city_num` | 返回城市编号(硬编码示例) |
| `get_weather` | 根据城市编号返回天气信息(硬编码示例) |
---
## 添加自定义工具
1.`functions/function_calling/` 目录下创建 Python 文件
2. 使用类型注解定义参数:
```python
from typing import Annotated
from utils.function_catalog import ParamMeta
def my_tool(
param1: Annotated[str, ParamMeta(description="参数描述")],
*,
_context: dict | None = None, # 可选,系统自动注入
) -> str:
"""函数描述(会显示给 LLM"""
return "result"
```
3. 重启后端服务器
4. 在 Agent 节点中通过 `name: my_tool``name: my_module:All` 引用
+92
View File
@@ -0,0 +1,92 @@
# MCP Tooling 指南
MCP 工具被明确拆分为 **Remote (HTTP)****Local (stdio)** 两种模式,对应 `tooling.type: mcp_remote``tooling.type: mcp_local`。旧的 `type: mcp` schema 已下线,请在 YAML 与文档中全部迁移。
## 1. 配置模式概览
| 模式 | Tooling type | 适用场景 | 关键字段 |
| --- | --- | --- | --- |
| Remote | `mcp_remote` | 已部署的 HTTP(S) MCP 服务器(如 FastMCP、Claude Desktop Connector、自建代理) | `server``headers``timeout` |
| Local | `mcp_local` | 通过 stdio 握手的本地可执行脚本(Blender MCP、CLI 工具等) | `command``args``cwd``env` 等进程字段 |
## 2. `McpRemoteConfig` 字段
| 字段 | 说明 |
| --- | --- |
| `server` | 必填,MCP HTTP(S) 端点,例如 `https://api.example.com/mcp`。 |
| `headers` | 可选,附加 HTTP 头(如 `Authorization`)。 |
| `timeout` | 可选,单次工具调用超时时间(秒)。 |
**YAML 示例:**
```yaml
nodes:
- id: remote_mcp
type: agent
config:
tooling:
type: mcp_remote
config:
server: https://mcp.mycompany.com/mcp
headers:
Authorization: Bearer ${MY_MCP_TOKEN}
timeout: 15
```
DevAll 会在列举/调用工具时连接该 URL,并携带 `headers`。若服务器不可达,将直接抛出错误,不再尝试本地回退。
## 3. `McpLocalConfig` 字段
`mcp_local` 直接在 `config` 下声明进程参数:
- `command` / `args`:可执行文件与参数(如 `uvx blender-mcp`)。
- `cwd`:可选工作目录。
- `env` / `inherit_env`:定制子进程环境;默认继承父进程后再覆盖。
- `startup_timeout`:等待 `wait_for_log` 命中的最长秒数。
- `wait_for_log`:stdout 正则,用于判定“就绪”。
**YAML 示例:**
```yaml
nodes:
- id: local_mcp
type: agent
config:
tooling:
type: mcp_local
config:
command: uvx
args:
- blender-mcp
cwd: ${REPO_ROOT}
wait_for_log: "MCP ready"
startup_timeout: 8
```
运行期间 DevAll 会保持该进程常驻,并通过 stdio 传输 MCP 数据帧。
## 4. FastMCP 示例服务器
`mcp_example/mcp_server.py`
```python
from fastmcp import FastMCP
import random
mcp = FastMCP("Company Simple MCP Server", debug=True)
@mcp.tool
def rand_num(a: int, b: int) -> int:
return random.randint(a, b)
if __name__ == "__main__":
mcp.run()
```
启动:
```bash
uv run fastmcp run mcp_example/mcp_server.py --transport streamable-http --port 8010
```
- 若以 Remote 模式使用,只需将 `server` 指向 `http://127.0.0.1:8010/mcp`
- 若以 Local 模式使用,可将 `command` 设置为 `uv run fastmcp run ...` 并保持 `transport=stdio`
## 5. 安全与运维
- **网络暴露**Remote 模式建议置于 HTTPS 反向代理之后,并结合 API Key/ACL;Local 模式进程仍可访问宿主机文件,请限制其权限。
- **资源回收**Local 模式由 DevAll 负责终止子进程,确保脚本可以正确处理 SIGTERM/SIGKILL。
- **日志定位**:为 `wait_for_log` 输出清晰的“ready”日志,便于在超时时排查。
- **鉴权**Remote 模式通过 `headers` 传递 TokenLocal 模式可在 `env` 中注入密钥,注意不要写入仓库。
- **多会话**:MCP 服务若不支持多客户端,可在模型或工具层设置 `max_concurrency=1` 并在 YAML 中复用同一配置。
## 6. 调试步骤
1. Remote:使用 curl 或 `fastmcp client` 测试 HTTP 端点;Local:先单独运行并确认 stdout 中有 `wait_for_log` 匹配的文本。
2. 启动 DevAll(可加 `--reload`),观察后端日志是否打印工具清单。
3. 若调用失败,查看 Web UI 中的工具请求/响应,或在 `logs/` 中搜索对应 session 的结构化日志。