From 2708531b1dd318afab020e7d0419c048622c6681 Mon Sep 17 00:00:00 2001 From: JackChen Date: Sat, 18 Apr 2026 19:48:13 +0800 Subject: [PATCH] docs: polish READMEs for 1.2 feature surface - Document AgentConfig.customTools alongside agent.addTool() - Add Tool Output Control section (maxToolOutputChars, maxOutputChars, compressToolResults) - Add Context Management section covering all four strategies (sliding-window, summarize, compact, custom) - Bump examples count 18 to 19 and add example 16 (MCP) and example 19 (Groq) to curated list - Sync README_zh with README: add CLI (oma) note, full MCP Tools section, Groq row in providers table - Drop stale rentech-quant-platform entry from Used by --- README.md | 85 ++++++++++++++++++++++++++++++++++++-- README_zh.md | 114 +++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 192 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index b84e104..89e9ed6 100644 --- a/README.md +++ b/README.md @@ -53,7 +53,6 @@ See [`DECISIONS.md`](./DECISIONS.md) for the full rationale. `open-multi-agent` is a new project (launched 2026-04-01, MIT, 5,500+ stars). The ecosystem is still forming, so the list below is short and honest: - **[temodar-agent](https://github.com/xeloxa/temodar-agent)** (~50 stars). WordPress security analysis platform by [Ali Sünbül](https://github.com/xeloxa). Uses our built-in tools (`bash`, `file_*`, `grep`) directly in its Docker runtime. Confirmed production use. -- **[rentech-quant-platform](https://github.com/rookiecoderasz/rentech-quant-platform).** Multi-agent quant trading research platform. Five pipelines plus MCP integrations, built on top of `open-multi-agent`. Early signal, very new. - **Cybersecurity SOC (home lab).** A private setup running Qwen 2.5 + DeepSeek Coder entirely offline via Ollama, building an autonomous SOC pipeline on Wazuh + Proxmox. Early user, not yet public. Using `open-multi-agent` in production or a side project? [Open a discussion](https://github.com/JackChen-me/open-multi-agent/discussions) and we will list it here. @@ -142,14 +141,16 @@ For MapReduce-style fan-out without task dependencies, use `AgentPool.runParalle ## Examples -18 runnable scripts and 1 full-stack demo in [`examples/`](./examples/). Start with these: +19 runnable scripts and 1 full-stack demo in [`examples/`](./examples/). Start with these: - [02 — Team Collaboration](examples/02-team-collaboration.ts): `runTeam()` coordinator pattern. - [06 — Local Model](examples/06-local-model.ts): Ollama and Claude in one pipeline via `baseURL`. - [09 — Structured Output](examples/09-structured-output.ts): any agent returns Zod-validated JSON. - [11 — Trace Observability](examples/11-trace-observability.ts): `onTrace` spans for LLM calls, tools, and tasks. +- [16 — MCP (GitHub)](examples/16-mcp-github.ts): expose an MCP server's tools to an agent via `connectMCPTools()`. - [17 — MiniMax](examples/17-minimax.ts): three-agent team using MiniMax M2.7. - [18 — DeepSeek](examples/18-deepseek.ts): three-agent team using DeepSeek Chat. +- [19 — Groq](examples/19-groq.ts): OpenAI-compatible Groq endpoint with fast free-tier models. - [with-vercel-ai-sdk](examples/with-vercel-ai-sdk/): Next.js app — OMA `runTeam()` + AI SDK `useChat` streaming. Run scripts with `npx tsx examples/02-team-collaboration.ts`. @@ -256,7 +257,58 @@ const customAgent: AgentConfig = { ### Custom Tools -Tools added via `agent.addTool()` are always available regardless of filtering. +Two ways to give an agent a tool that is not in the built-in set. + +**Inject at config time** via `customTools` on `AgentConfig`. Good when the orchestrator wires up tools centrally. Tools defined here bypass preset/allowlist filtering but still respect `disallowedTools`. + +```typescript +import { defineTool } from '@jackchen_me/open-multi-agent' +import { z } from 'zod' + +const weatherTool = defineTool({ + name: 'get_weather', + description: 'Look up current weather for a city.', + schema: z.object({ city: z.string() }), + execute: async ({ city }) => ({ content: await fetchWeather(city) }), +}) + +const agent: AgentConfig = { + name: 'assistant', + model: 'claude-sonnet-4-6', + customTools: [weatherTool], +} +``` + +**Register at runtime** via `agent.addTool(tool)`. Tools added this way are always available, regardless of filtering. + +### Tool Output Control + +Long tool outputs can blow up conversation size and cost. Two controls work together. + +**Truncation** — cap an individual tool result to a head + tail excerpt with a marker in between: + +```typescript +const agent: AgentConfig = { + // ... + maxToolOutputChars: 10_000, // applies to every tool this agent runs +} + +// Per-tool override (takes priority over AgentConfig.maxToolOutputChars): +const bigQueryTool = defineTool({ + // ... + maxOutputChars: 50_000, +}) +``` + +**Post-consumption compression** — once the agent has acted on a tool result, compress older copies in the transcript so they stop costing input tokens on every subsequent turn. Error results are never compressed. + +```typescript +const agent: AgentConfig = { + // ... + compressToolResults: true, // default threshold: 500 chars + // or: compressToolResults: { minChars: 2_000 } +} +``` ### MCP Tools (Model Context Protocol) @@ -282,6 +334,33 @@ Notes: - Current transport support is stdio. - MCP input validation is delegated to the MCP server (`inputSchema` is `z.any()`). +See [example 16](examples/16-mcp-github.ts) for a full runnable setup. + +## Context Management + +Long-running agents can hit input token ceilings fast. Set `contextStrategy` on `AgentConfig` to control how the conversation shrinks as it grows: + +```typescript +const agent: AgentConfig = { + name: 'long-runner', + model: 'claude-sonnet-4-6', + // Pick one: + contextStrategy: { type: 'sliding-window', maxTurns: 20 }, + // contextStrategy: { type: 'summarize', maxTokens: 80_000, summaryModel: 'claude-haiku-4-5' }, + // contextStrategy: { type: 'compact', maxTokens: 100_000, preserveRecentTurns: 4 }, + // contextStrategy: { type: 'custom', compress: (messages, estimatedTokens, ctx) => ... }, +} +``` + +| Strategy | When to reach for it | +|----------|----------------------| +| `sliding-window` | Cheapest. Keep the last N turns, drop the rest. | +| `summarize` | Send old turns to a summary model; keep the summary in place of the originals. | +| `compact` | Rule-based: truncate large assistant text blocks and tool results, keep recent turns intact. No extra LLM call. | +| `custom` | Supply your own `compress(messages, estimatedTokens, ctx)` function. | + +Pairs well with `compressToolResults` and `maxToolOutputChars` above. + ## Supported Providers | Provider | Config | Env var | Status | diff --git a/README_zh.md b/README_zh.md index aa9c83e..ca33c68 100644 --- a/README_zh.md +++ b/README_zh.md @@ -53,7 +53,6 @@ CrewAI 是 Python。LangGraph 需要你自己画图。`open-multi-agent` 是你 `open-multi-agent` 是一个新项目(2026-04-01 发布,MIT 许可,5,500+ stars)。生态还在成形,下面这份列表很短,但都真实: - **[temodar-agent](https://github.com/xeloxa/temodar-agent)**(约 50 stars)。WordPress 安全分析平台,作者 [Ali Sünbül](https://github.com/xeloxa)。在 Docker runtime 里直接使用我们的内置工具(`bash`、`file_*`、`grep`)。已确认生产环境使用。 -- **[rentech-quant-platform](https://github.com/rookiecoderasz/rentech-quant-platform)。** 多智能体量化交易研究平台,5 条管线 + MCP 集成,基于 `open-multi-agent` 构建。早期信号,项目非常新。 - **家用服务器 Cybersecurity SOC。** 本地完全离线运行 Qwen 2.5 + DeepSeek Coder(通过 Ollama),在 Wazuh + Proxmox 上构建自主 SOC 流水线。早期用户,未公开。 你在生产环境或 side project 里用 `open-multi-agent` 吗?[开一个 Discussion](https://github.com/JackChen-me/open-multi-agent/discussions),我们会把你列上来。 @@ -77,6 +76,8 @@ npm install @jackchen_me/open-multi-agent - `DEEPSEEK_API_KEY`(DeepSeek) - `GITHUB_TOKEN`(Copilot) +**CLI (`oma`)。** 面向 shell 和 CI,包自带一个 JSON-first 的二进制。`oma run`、`oma task`、`oma provider`、退出码和文件格式见 [docs/cli.md](./docs/cli.md)。 + 三个智能体,一个目标——框架处理剩下的一切: ```typescript @@ -140,14 +141,16 @@ Tokens: 12847 output tokens ## 示例 -[`examples/`](./examples/) 里有 18 个可运行脚本和 1 个完整项目。推荐从这几个开始: +[`examples/`](./examples/) 里有 19 个可运行脚本和 1 个完整项目。推荐从这几个开始: - [02 — 团队协作](examples/02-team-collaboration.ts):`runTeam()` 协调者模式。 - [06 — 本地模型](examples/06-local-model.ts):通过 `baseURL` 把 Ollama 和 Claude 放在同一条管线。 - [09 — 结构化输出](examples/09-structured-output.ts):任意 agent 产出 Zod 校验过的 JSON。 - [11 — 可观测性](examples/11-trace-observability.ts):`onTrace` 回调,为 LLM 调用、工具、任务发出结构化 span。 +- [16 — MCP (GitHub)](examples/16-mcp-github.ts):通过 `connectMCPTools()` 把 MCP 服务器的工具暴露给 agent。 - [17 — MiniMax](examples/17-minimax.ts):使用 MiniMax M2.7 的三智能体团队。 - [18 — DeepSeek](examples/18-deepseek.ts):使用 DeepSeek Chat 的三智能体团队。 +- [19 — Groq](examples/19-groq.ts):OpenAI 兼容的 Groq 端点,搭配高速免费档模型。 - [with-vercel-ai-sdk](examples/with-vercel-ai-sdk/):Next.js 应用 — OMA `runTeam()` + AI SDK `useChat` 流式输出。 用 `npx tsx examples/02-team-collaboration.ts` 运行脚本示例。 @@ -254,7 +257,109 @@ const customAgent: AgentConfig = { ### 自定义工具 -通过 `agent.addTool()` 添加的工具始终可用,不受过滤规则影响。 +两种方式给 agent 装一个不在内置工具集里的工具。 + +**配置时注入**:通过 `AgentConfig.customTools` 传入。适合编排层统一挂工具的场景。这里定义的工具会绕过 preset / 白名单过滤,但仍受 `disallowedTools` 约束。 + +```typescript +import { defineTool } from '@jackchen_me/open-multi-agent' +import { z } from 'zod' + +const weatherTool = defineTool({ + name: 'get_weather', + description: '查询某城市当前天气。', + schema: z.object({ city: z.string() }), + execute: async ({ city }) => ({ content: await fetchWeather(city) }), +}) + +const agent: AgentConfig = { + name: 'assistant', + model: 'claude-sonnet-4-6', + customTools: [weatherTool], +} +``` + +**运行时注册**:`agent.addTool(tool)`。这种方式添加的工具始终可用,不受任何过滤规则影响。 + +### 工具输出控制 + +工具返回过长会迅速撑大对话体积和成本。两个控制点互相配合。 + +**截断** — 把单次工具结果压到 head + tail 摘要(中间放一个标记): + +```typescript +const agent: AgentConfig = { + // ... + maxToolOutputChars: 10_000, // 该 agent 所有工具的默认上限 +} + +// 单工具覆盖(优先级高于 AgentConfig.maxToolOutputChars): +const bigQueryTool = defineTool({ + // ... + maxOutputChars: 50_000, +}) +``` + +**消费后压缩** — agent 在后续轮次已经用完某个工具结果后,把历史副本压缩,避免每轮都重复消耗输入 token。错误结果永不压缩。 + +```typescript +const agent: AgentConfig = { + // ... + compressToolResults: true, // 默认阈值 500 字符 + // 或:compressToolResults: { minChars: 2_000 } +} +``` + +### MCP 工具(Model Context Protocol) + +`open-multi-agent` 可以连接任意 MCP 服务器,并把它的工具直接暴露给 agent。 + +```typescript +import { connectMCPTools } from '@jackchen_me/open-multi-agent/mcp' + +const { tools, disconnect } = await connectMCPTools({ + command: 'npx', + args: ['-y', '@modelcontextprotocol/server-github'], + env: { GITHUB_TOKEN: process.env.GITHUB_TOKEN }, + namePrefix: 'github', +}) + +// 把每个 MCP 工具注册进你的 ToolRegistry,然后在 AgentConfig.tools 里引用它们的名字 +// 用完别忘了清理 +await disconnect() +``` + +注意事项: +- `@modelcontextprotocol/sdk` 是 optional peer dependency,只在用 MCP 时才需要装。 +- 当前仅支持 stdio transport。 +- MCP 的入参校验交给 MCP 服务器自身(`inputSchema` 是 `z.any()`)。 + +完整可运行示例见 [example 16](examples/16-mcp-github.ts)。 + +## 上下文管理 + +长时间运行的 agent 很容易撞上输入 token 上限。在 `AgentConfig` 上设置 `contextStrategy` 来控制对话在成长过程中如何收缩: + +```typescript +const agent: AgentConfig = { + name: 'long-runner', + model: 'claude-sonnet-4-6', + // 选一种: + contextStrategy: { type: 'sliding-window', maxTurns: 20 }, + // contextStrategy: { type: 'summarize', maxTokens: 80_000, summaryModel: 'claude-haiku-4-5' }, + // contextStrategy: { type: 'compact', maxTokens: 100_000, preserveRecentTurns: 4 }, + // contextStrategy: { type: 'custom', compress: (messages, estimatedTokens, ctx) => ... }, +} +``` + +| 策略 | 什么时候用 | +|------|------------| +| `sliding-window` | 最省事。只保留最近 N 轮,其余丢弃。 | +| `summarize` | 把老对话交给一个摘要模型,用摘要替代原文。 | +| `compact` | 基于规则:截断过长的 assistant 文本块和 tool 结果,保留最近若干轮。不额外调用 LLM。 | +| `custom` | 传入自己的 `compress(messages, estimatedTokens, ctx)` 函数。 | + +搭配上面的 `compressToolResults` 和 `maxToolOutputChars` 使用效果更好。 ## 支持的 Provider @@ -269,13 +374,14 @@ const customAgent: AgentConfig = { | GitHub Copilot | `provider: 'copilot'` | `GITHUB_TOKEN` | 已验证 | | Gemini | `provider: 'gemini'` | `GEMINI_API_KEY` | 已验证 | | Ollama / vLLM / LM Studio | `provider: 'openai'` + `baseURL` | — | 已验证 | +| Groq | `provider: 'openai'` + `baseURL` | `GROQ_API_KEY` | 已验证 | | llama.cpp server | `provider: 'openai'` + `baseURL` | — | 已验证 | Gemini 需要 `npm install @google/genai`(optional peer dependency)。 已验证支持 tool-calling 的本地模型:**Gemma 4**(见[示例 08](examples/08-gemma4-local.ts))。 -任何 OpenAI 兼容 API 均可通过 `provider: 'openai'` + `baseURL` 接入(Groq、Mistral、Qwen 等)。**Grok、MiniMax 和 DeepSeek 现已原生支持**,分别使用 `provider: 'grok'`、`provider: 'minimax'` 和 `provider: 'deepseek'`。 +任何 OpenAI 兼容 API 均可通过 `provider: 'openai'` + `baseURL` 接入(Mistral、Qwen、Moonshot、Doubao 等)。Groq 已在[示例 19](examples/19-groq.ts) 中验证。**Grok、MiniMax 和 DeepSeek 现已原生支持**,分别使用 `provider: 'grok'`、`provider: 'minimax'` 和 `provider: 'deepseek'`。 ### 本地模型 Tool-Calling