手把手书写你的第一个 AI Agent:当 Skill 有了记忆、角色和主动性

手把手书写你的第一个 AI Agent:当 Skill 有了记忆、角色和主动性

前端 AI Skill 体系 · 第 6 篇(Agent 篇)

上一篇,我们花 15 分钟写了一个日报生成器 Skill。30 行 Markdown,AI 从此不再每天失忆。

但用了一周之后,我发现一个问题:Skill 不会主动干活。

我不说"写日报",它就沉默。我不说"审查代码",它就装死。它像一个只会听指令的实习生------你推一下,它动一下。

我想要的是一个同事:自己记得上下文,自己判断下一步做什么,做完了还会主动告诉我结果。

这就是 Agent。今天这篇,我们从零搭一个。


一、先搞清楚:Agent 和 Skill 到底什么区别

上一篇发布后,评论区问得最多的就是:"Skill 和 Agent 不就是叫法不同吗?"

不是。区别是本质性的。

一句话版本

Skill 是岗位说明书,Agent 是一个活人。

说明书贴在工位上,谁来都照着做。它不会主动思考,不会记住昨天发生了什么,更不会在发现问题时自己去找隔壁部门协调。

Agent 会。

展开说

维度 Skill Agent
本质 一份 Markdown 指令 一个可运行的程序
触发 被动------你说话它才动 主动------自己决定何时行动
记忆 无。每次对话从零开始 有。短期工作记忆 + 长期持久化
工具 描述"应该做什么",AI 自行决定 代码级绑定,确定性执行
决策 线性流程,不会回溯 观察→思考→行动→再观察,循环
协作 独立存在,互不感知 Handoff 给其他 Agent、组队
部署 放项目目录就行 需要 Python/Node 运行时
成本 零(纯文本) API 调用费 / 本地算力

什么时候该用哪个?

我现在的判断标准很简单:

如果任务需要"做完一步,看看结果,再决定下一步"------用 Agent。 如果任务是"输入→固定流程→输出"------用 Skill。

举几个实际例子:

场景 选择 为什么
统一代码风格 Skill 规则固定,不需要决策
生成日报 Skill 流程固定,一次执行完事
自动修 Bug Agent 要观察报错→定位原因→修复→验证→没修好再来
多文件重构 Agent 要规划顺序、跨文件协调、改完一个检查另一个
客服问答 Agent 要记住上下文、查知识库、判断是否需要转人工
代码审查 Skill + Agent Skill 定审查规则,Agent 执行多轮审查

它们不是替代关系,是互补关系。 Skill 定义"怎么做",Agent 决定"什么时候做、找谁做、做完了怎么办"。

我现在的体系里,31 个 Skill 定义规范,3 个 Agent 负责编排和执行。Skill 是法律条文,Agent 是法官。


二、项目目录结构

简单 Agent:5 个文件搞定

bash 复制代码
my-first-agent/
├── agent.py              # Agent 定义(角色 + 指令 + 工具绑定)
├── tools.py              # 工具函数(Agent 的手和脚)
├── main.py               # 运行入口
├── requirements.txt      # 依赖:openai-agents
└── .env                  # API Key(别提交 Git)

就这么多。别一上来就搞 20 个目录。

复杂 Agent:5 层架构

当你的 Agent 从 1 个变成 3 个、5 个,目录就需要分层了:

perl 复制代码
my-agent-system/
│
├── agents/               # 🧠 角色层:谁干什么
│   ├── orchestrator.py   #    编排者------决定任务分配
│   ├── researcher.py     #    研究员------搜索和整理信息
│   ├── coder.py          #    开发者------写代码、修 Bug
│   └── reviewer.py       #    审查者------质量把关
│
├── tools/                # 🔧 能力层:能做什么
│   ├── web_search.py     #    网络搜索
│   ├── file_ops.py       #    文件读写
│   ├── code_exec.py      #    代码执行(沙箱)
│   └── git_ops.py        #    Git 操作
│
├── memory/               # 💾 记忆层:记得什么
│   ├── short_term.py     #    当前对话上下文
│   ├── long_term.py      #    跨会话持久化(SQLite/Redis)
│   └── vector_store.py   #    语义检索(向量数据库)
│
├── config/               # ⚙️ 配置层:用什么模型、什么参数
│   ├── models.py         #    模型配置(可切换 OpenAI/Claude/Ollama)
│   ├── prompts.py        #    System Prompt 模板
│   └── settings.py       #    全局设置(max_iterations、timeout)
│
├── workflows/            # 🔄 编排层:怎么协作
│   ├── code_review.py    #    代码审查流程
│   └── feature_dev.py    #    功能开发流程(含回退重试)
│
├── main.py               # 入口
├── requirements.txt
├── .env.example
└── README.md

各层一句话

一句话 类比
agents/ 定义"谁"------角色、目标、边界 公司组织架构
tools/ 定义"能做什么"------具体能力 员工的工具箱
memory/ 定义"记得什么"------上下文和知识 员工的大脑
config/ 定义"用什么模型" 公司制度
workflows/ 定义"怎么协作" 项目流程

原则:先跑通 5 个文件的简单版,再按需拆层。 别一上来就搭 5 层架构------那是第 3 个 Agent 出现之后才需要的事。


三、5 个我踩过的坑

这些坑我全踩过。每一个都浪费了我至少半天。

坑 1:以为长 Prompt = Agent

我最初的"Agent"就是一个 3000 字的 System Prompt,里面写了"你要先搜索,再分析,再输出"。

它不是 Agent。它是一个带长说明书的 Chatbot

Agent 的核心不是 Prompt 长度,是循环

python 复制代码
# ❌ 这不是 Agent,这是一个函数调用
response = llm.call("帮我调研 xxx")

# ✅ Agent 的核心是这个循环
while not done:
    observation = agent.observe(environment)    # 看到了什么
    thought = agent.think(observation)          # 怎么想的
    action = agent.decide(thought)              # 决定做什么
    result = agent.act(action)                  # 执行
    done = agent.evaluate(result)               # 够了吗?不够就再来

这个循环叫 ReAct(Reasoning + Acting)。没有它,就不是 Agent。

坑 2:给 Agent 接了 30 个工具

"工具越多越强大嘛!"------我当初是这么想的。

结果:Agent 开始"选择困难"。让它搜个东西,它先去读了个文件。让它写代码,它先去搜了个网页。

实测体感

工具数量 任务准确率(体感)
3-5 个 ~90%
10-15 个 ~70%
30+ 个 开始随机调工具,~50%

原则:每个 Agent 最多 5-7 个工具。 需要更多能力?拆成多个 Agent,每个 Agent 只管自己那几把刀。

坑 3:造了一个"全能 Agent"

python 复制代码
# ❌ 我最初写的
agent = Agent(
    name="Everything",
    instructions="你能搜索、写代码、审查代码、部署、写文档、做PPT..."
)

它什么都做,什么都做不好。

后来我拆成了 3 个:Researcher 只管搜、Coder 只管写、Reviewer 只管审。每个 Agent 的 instructions 不超过 200 字。

效果立竿见影:单个 Agent 的输出质量从"勉强能用"变成"基本不用改"。

坑 4:没设最大循环次数

有一天晚上我让 Agent 调研一个技术方案,然后去吃饭了。

回来一看:它还在跑。 搜了 47 次网页,每次都觉得"信息不够充分,再搜一次"。Token 烧了 $3.2。

python 复制代码
# ✅ 必须设上限
result = await Runner.run(
    agent,
    "调研 xxx",
    max_turns=10,  # 最多 10 轮工具调用,超了就停
)

教训:Agent 没有"够了"的概念,你必须替它设。

坑 5:没做 Human-in-the-loop

我让 Agent 帮我"清理项目里的临时文件"。

它很勤快地执行了 rm -rf node_modules .git dist

.git 没了。

python 复制代码
# ✅ 危险操作必须暂停等人确认
from agents import Agent, function_tool

@function_tool(needs_approval=True)  # 关键:执行前暂停等人确认
def delete_file(path: str) -> str:
    """删除指定文件"""
    os.remove(path)
    return f"已删除 {path}"

2026 年了,Agent 仍然需要人类把关。 尤其是:删除操作、金钱相关、权限变更、面向外部的输出。

个人 vs 企业:方向不同

维度 个人开发者(我) 企业团队
起步 OpenAI Agents SDK,单文件 LangGraph / CrewAI + 编排平台
模型 OpenAI / Claude API 私有部署 + API 混合
记忆 本地 SQLite Redis + 向量数据库
部署 本地跑 / 简单脚本 K8s + 监控 + 告警
安全 .env 管 Key Vault + RBAC + 审计日志
月成本 $10-50 预算制,需成本监控
可观测 print + Tracing 面板 LangSmith / 专业 Tracing

如果你是一个人,别搞企业那套。 一个 .py 文件 + 一个 .env,够了。


四、15 分钟:搭一个能搜索、能写文件的 Research Agent

框架选择:OpenAI Agents SDK。 原因:5 行代码跑起来,内置 Tracing,支持 100+ 模型,2026 年社区最活跃。 后面复杂版也用它,不换框架。

Step 1:环境准备(2 分钟)

前置要求 :Python 3.10+(python3 --version 检查)。 前端同学如果没装过 Python:macOS 用 brew install python@3.12,Windows 去 python.org 下载安装。

bash 复制代码
mkdir my-first-agent && cd my-first-agent
python3 -m venv .venv
source .venv/bin/activate  # Windows: .venv\Scripts\activate

pip install openai-agents python-dotenv

# 环境变量(这里用阿里百炼/通义千问,国内直连,不用翻墙)
# 到 https://bailian.console.aliyun.com 开通,免费额度够跑几十次
cat > .env << EOF
OPENAI_API_KEY=sk-xxx          # 百炼的 API Key
OPENAI_BASE_URL=https://dashscope.aliyuncs.com/compatible-mode/v1
TAVILY_API_KEY=tvly-xxx        # 搜索工具用,https://tavily.com 免费注册
EOF

echo ".env" >> .gitignore

为什么用百炼而不是 OpenAI? 三个原因:国内直连不用代理、免费额度够学习用、qwen-plus 的中文能力很强。后面第六章会讲怎么切回 OpenAI 或本地 Ollama。

Step 2:写工具(5 分钟)

工具就是 Agent 的手和脚。没有工具的 Agent 只是一个会说话的嘴。

python 复制代码
# tools.py
import subprocess
from pathlib import Path
from agents import function_tool


@function_tool
def web_search(query: str) -> str:
    """搜索网络获取最新信息。当需要查找实时数据、技术文档、新闻时使用。

    Args:
        query: 搜索关键词,尽量具体。比如"OpenAI Agents SDK 2026 新特性"比"AI框架"好。
    """
    import json, os
    api_key = os.getenv("TAVILY_API_KEY", "")
    if not api_key:
        return "错误:未设置 TAVILY_API_KEY 环境变量。请到 https://tavily.com 免费注册获取。"
    try:
        result = subprocess.run(
            ["curl", "-s", "-X", "POST", "https://api.tavily.com/search",
             "-H", "Content-Type: application/json",
             "-d", json.dumps({"api_key": api_key, "query": query, "max_results": 3})],
            capture_output=True, text=True, timeout=15
        )
        data = json.loads(result.stdout)
        summaries = [f"- {r.get('title', '')}: {r.get('content', '')[:300]}" for r in data.get("results", [])]
        return "\n".join(summaries)[:2000] if summaries else "未找到相关结果"
    except (subprocess.TimeoutExpired, json.JSONDecodeError) as e:
        return f"搜索失败:{e},请换个关键词重试"


@function_tool
def read_file(file_path: str) -> str:
    """读取本地文件内容。当需要查看代码、文档、配置文件时使用。

    Args:
        file_path: 文件的相对或绝对路径
    """
    path = Path(file_path)
    if not path.exists():
        return f"文件不存在:{file_path}"
    if path.stat().st_size > 50_000:
        return f"文件过大({path.stat().st_size} 字节),请指定行号范围"
    return path.read_text(encoding="utf-8")[:5000]


@function_tool
def write_file(file_path: str, content: str) -> str:
    """将内容写入文件。当需要保存研究结果、生成报告时使用。

    Args:
        file_path: 目标文件路径
        content: 要写入的完整内容
    """
    path = Path(file_path)
    path.parent.mkdir(parents=True, exist_ok=True)
    path.write_text(content, encoding="utf-8")
    return f"✅ 已写入 {file_path}({len(content)} 字符)"

3 个细节,都是踩坑后加的

  1. docstring 里写"什么时候用"------Agent 靠这段话决定调不调这个工具
  2. 返回值必须截断[:2000])------不截断,一次搜索就吃掉 50% 上下文
  3. 错误要返回字符串,不要抛异常------Agent 看到错误信息会自己重试

Step 3:定义 Agent(3 分钟)

python 复制代码
# agent.py
from agents import Agent
from tools import web_search, read_file, write_file

research_agent = Agent(
    name="Research Assistant",
    model="qwen-plus",  # 百炼模型名。用 OpenAI 就改成 "gpt-4o"
    instructions="""你是一个研究助理。

## 工作流程
1. 理解用户的研究问题,拆解为 2-3 个子问题
2. 对每个子问题使用 web_search 搜索
3. 评估信息是否充分------不够就换关键词再搜
4. 整理为结构化报告,用 write_file 保存到 reports/ 目录

## 规则
- 每次搜索后问自己:"信息够回答问题了吗?"不够就继续
- 报告必须标注信息来源 URL
- 不确定的信息标注【待验证】
- 最多搜索 5 次。5 次还不够,就如实说"信息有限"
- 报告用中文,技术术语保留英文""",
    tools=[web_search, read_file, write_file],
)

注意 instructions 的写法

  • 有明确的工作流程(不是"你帮我调研一下"这种模糊指令)
  • 有退出条件("最多 5 次")------防止坑 4 的无限循环
  • 有输出规范("标注来源"、"用中文")
  • model 字段指定模型------百炼用 qwen-plus,OpenAI 用 gpt-4o,本地用 llama3.1:8b

Step 4:运行(2 分钟)

python 复制代码
# main.py
from dotenv import load_dotenv
load_dotenv()

import os
os.environ["OPENAI_AGENTS_DISABLE_TRACING"] = "true"

import asyncio
from agents import Runner, set_default_openai_api
from agent import research_agent

# 百炼不支持 Responses API,强制走 Chat Completions API
set_default_openai_api("chat_completions")


async def main():
    user_input = input("请输入你的研究问题(直接回车使用默认问题):\n> ").strip()
    if not user_input:
        user_input = "调研 2026 年主流 AI Agent 框架(OpenAI Agents SDK、LangGraph、CrewAI)的优劣对比"

    result = await Runner.run(
        research_agent,
        input=user_input,
        max_turns=10,
    )
    print(result.final_output)


if __name__ == "__main__":
    asyncio.run(main())
bash 复制代码
python main.py

两行"丑代码",但缺了直接报错

代码 为什么需要 用 OpenAI 时
OPENAI_AGENTS_DISABLE_TRACING=true 百炼不支持 OpenAI 的 Tracing 上报 删掉,享受内置 Tracing
set_default_openai_api("chat_completions") 百炼只支持 Chat Completions API 删掉,SDK 默认即可

Step 5:看它怎么想的(3 分钟)

运行后你会在终端看到 Agent 的完整决策链:

css 复制代码
Turn 1: Agent 思考 → 拆解为 3 个子问题
Turn 2: 调用 web_search("OpenAI Agents SDK features 2026")
Turn 3: 调用 web_search("LangGraph vs CrewAI comparison")
Turn 4: 调用 web_search("AI agent framework benchmark 2026")
Turn 5: Agent 思考 → 信息充分,开始写报告
Turn 6: 调用 write_file("reports/agent-frameworks-2026.md", ...)
Turn 7: 输出最终摘要

如果你用的是 OpenAI 官方 API(没关 Tracing),还可以打开 platform.openai.com/traces 看可视化面板。

这就是 Agent 和 Chatbot 的区别:Chatbot 给你一坨文字,Agent 给你一条可审计的决策链。

最终文件清单

bash 复制代码
my-first-agent/
├── agent.py          # 22 行:Agent 定义
├── tools.py          # 50 行:3 个工具
├── main.py           # 25 行:运行入口
├── requirements.txt  # 2 行:openai-agents + python-dotenv
└── .env              # 3 行:API Key + Base URL + Tavily Key

~100 行代码。一个能搜索、能读写文件、有决策循环的 Agent。国内直连,不用代理。


五、45 分钟:搭一个 3 人协作的开发团队

还是 OpenAI Agents SDK。不换框架。 从 1 个 Agent 到 3 个,核心变化是:Handoff(任务移交)

目标

输入一句需求:"实现一个 React useDebounce Hook"。

3 个 Agent 自动协作:

  1. PM Agent 分析需求 → 输出技术方案
  2. Coder Agent 根据方案写代码 → 输出到 src/
  3. Reviewer Agent 审查代码 → 通过或打回

如果审查不通过,自动打回给 Coder 重写,最多重试 2 次。

环境准备

和第四章一样,需要 Python 3.10+ 环境。如果你已经跑通了第四章,直接复用那个虚拟环境即可------依赖完全相同。

bash 复制代码
# 如果还没装过:
python3 -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt

本章复用第四章的 tools.pyrequirements.txt,不需要额外安装任何新依赖。

Step 1:定义 3 个 Agent

python 复制代码
# agents.py
from agents import Agent, function_tool
from tools import read_file, write_file

# ---------- PM Agent ----------
pm_agent = Agent(
    name="PM",
    model="qwen-plus",
    instructions="""你是技术产品经理。

## 职责
将用户需求转化为可执行的技术方案。

## 输出格式(严格遵守)
### 功能描述
一句话说明做什么。

### 接口定义
- 输入:参数名、类型、默认值
- 输出:返回值类型
- 用法示例:```tsx 代码块

### 边界条件(至少 3 个)
1. ...
2. ...
3. ...

### 验收标准(可测试的 checklist)
- [ ] ...
- [ ] ...

## 规则
- 先问"用户真正想要什么",不要直接设计
- 如果需求模糊,列出你的假设
- 不写代码,只写方案""",
    tools=[read_file],
)

# ---------- Coder Agent ----------
coder_agent = Agent(
    name="Coder",
    model="qwen-plus",
    instructions="""你是高级前端工程师。

## 职责
根据技术方案编写代码。

## 规则
- 代码写入 src/ 目录(用 write_file 工具)
- 主文件:src/index.ts
- 测试文件:src/index.test.ts
- 所有函数必须有 JSDoc 注释
- 错误处理不能省略
- 如果方案有歧义,在代码注释中标注 // TODO: 方案歧义 - xxx
- 使用 TypeScript strict 模式""",
    tools=[read_file, write_file],
)

# ---------- Reviewer Agent ----------
reviewer_agent = Agent(
    name="Reviewer",
    model="qwen-plus",
    instructions="""你是代码审查专家。

## 审查维度(按优先级)
1. 逻辑正确性------对照技术方案的验收标准逐条检查
2. 边界条件------方案里列的边界条件是否都处理了
3. 错误处理------有没有吞掉异常
4. 类型安全------有没有 any
5. 性能------有没有不必要的重渲染/重复计算

## 输出格式
如果通过:
"LGTM ✅" + 一句话总结亮点

如果不通过:
"NEEDS_REVISION ❌" + 具体问题列表(精确到行号 + 修改建议)

## 规则
- 目标是帮助,不是刁难
- 风格问题(分号、缩进)不提
- 最多提 5 个问题,挑最严重的""",
    tools=[read_file],
)

Step 2:定义 Handoff 和编排

python 复制代码
# workflow.py
from agents import Agent, Runner, handoff
from agents.stream_events import RunItemStreamEvent, AgentUpdatedStreamEvent
from agent import pm_agent, coder_agent, reviewer_agent

# 给 PM 添加 Handoff:分析完交给 Coder
pm_agent.handoffs = [handoff(coder_agent)]

# 给 Coder 添加 Handoff:写完交给 Reviewer
coder_agent.handoffs = [handoff(reviewer_agent)]

# Reviewer 的 Handoff:打回给 Coder(条件触发)
reviewer_agent.handoffs = [handoff(coder_agent)]

def _format_event(event):
    """格式化流式事件为可读输出"""
    if isinstance(event, AgentUpdatedStreamEvent):
        print(f"\n🤖 [{event.new_agent.name}] 接管中...")

    elif isinstance(event, RunItemStreamEvent):
        name = event.name
        item = event.item

        if name == "message_output_created":
            text = getattr(item, 'raw_item', None)
            if text:
                content = getattr(text, 'content', '')
                if isinstance(content, list):
                    for c in content:
                        if hasattr(c, 'text') and c.text:
                            print(f"  💬 {c.text[:200]}")
                elif isinstance(content, str) and content.strip():
                    print(f"  💬 {content[:200]}")

        elif name == "tool_called":
            tool_name = getattr(item, 'name', 'unknown')
            print(f"  🔧 调用工具: {tool_name}")

        elif name == "tool_output":
            print(f"  ✅ 工具执行完成")

        elif name == "handoff_requested":
            print(f"  ➡️  请求交接...")

        elif name == "handoff_occured":
            print(f"  🔀 交接完成")

async def run_dev_team(requirement: str) -> str:
    """运行开发团队,实时展示每个 Agent 的执行过程"""
    result = Runner.run_streamed(
        pm_agent,
        input=f"需求:{requirement}\n\n请分析需求并输出技术方案,然后交给 Coder 实现。",
        max_turns=20,
    )

    async for event in result.stream_events():
        _format_event(event)

    return result.final_output

这里用了 Runner.run_streamed 替代 Runner.run------区别在于你能实时看到每个 Agent 在干什么:谁接管了、调了什么工具、输出了什么。调试多 Agent 协作时,这比等最终结果强太多。

Step 3:加入重试逻辑

python 复制代码
# main.py
from dotenv import load_dotenv
load_dotenv()

import os
os.environ["OPENAI_AGENTS_DISABLE_TRACING"] = "true"

import asyncio
from agents import set_default_openai_api
from workflow import run_dev_team

# 百炼/通义千问不支持 Responses API,强制使用 Chat Completions API
set_default_openai_api("chat_completions")


async def main():
    default_req = "实现一个 React Hook:useDebounce,支持自定义延迟(默认 300ms)、取消、立即执行(flush)"
    user_input = input(f"请输入开发需求(直接回车使用默认需求):\n> ").strip()
    requirement = user_input if user_input else default_req

    max_retries = 2

    for attempt in range(max_retries + 1):
        print(f"\n{'='*50}")
        print(f"🚀 第 {attempt + 1} 轮")
        print(f"{'='*50}")

        result = await run_dev_team(requirement)

        if "LGTM" in result:
            print("\n✅ 审查通过!代码已写入 src/ 目录")
            break
        elif attempt < max_retries:
            print(f"\n❌ 审查未通过,打回重写(剩余 {max_retries - attempt} 次机会)")
            requirement += f"\n\n上一轮审查意见:\n{result}"
        else:
            print("\n⚠️ 重试次数用完,需要人工介入")
            print(result)


if __name__ == "__main__":
    asyncio.run(main())

和第四章一样,三件套不能少:load_dotenv() 加载 .env、禁用 Tracing、强制 Chat Completions API。忘了任何一行都会报错。

Step 4:运行

bash 复制代码
python main.py

你会看到:

csharp 复制代码
==================================================
🚀 第 1 轮
==================================================
[PM] 分析需求...
  → 输出技术方案:接口定义、边界条件、验收标准
  → Handoff to Coder

[Coder] 编写代码...
  → write_file("src/index.ts", ...)
  → write_file("src/index.test.ts", ...)
  → Handoff to Reviewer

[Reviewer] 审查代码...
  → NEEDS_REVISION ❌
  → 问题 1: src/index.ts:23 - flush 后没有清除 timer
  → 问题 2: src/index.test.ts - 缺少 cancel 的测试用例

❌ 审查未通过,打回重写(剩余 2 次机会)

==================================================
🚀 第 2 轮
==================================================
[Coder] 根据审查意见修改...
  → 修复 flush 逻辑
  → 补充 cancel 测试
  → Handoff to Reviewer

[Reviewer] 再次审查...
  → LGTM ✅ 逻辑完整,边界条件全覆盖

✅ 审查通过!代码已写入 src/ 目录

架构图

css 复制代码
┌──────────────────────────────────────────────────────┐
│                  Dev Team Workflow                     │
│                                                       │
│  ┌────────┐  Handoff  ┌────────┐  Handoff  ┌────────┐│
│  │   PM   │─────────▶│ Coder  │─────────▶│Reviewer││
│  │ 需求分析│          │ 编码实现│          │ 代码审查││
│  └────────┘          └────────┘          └───┬────┘│
│                            ▲                  │      │
│                            │  NEEDS_REVISION  │      │
│                            └──────────────────┘      │
│                                                       │
│  外部循环:main.py 控制最多重试 2 次                    │
│  超过 2 次 → 人工介入                                  │
└──────────────────────────────────────────────────────┘

和简单版的区别

维度 简单版(1 Agent) 复杂版(3 Agent)
Agent 数量 1 3
工具分配 1 个 Agent 拿所有工具 每个 Agent 只拿自己需要的
协作方式 Handoff 移交
质量控制 自己检查自己 独立 Reviewer
失败处理 打回重写 + 重试上限

六、换模型:从 OpenAI 到本地 Ollama

前面用的都是云端 API(百炼)。但有些场景你需要换:

  • 隐私:代码不能出公司
  • 成本:高频简单任务,API 费太贵
  • 离线:没网也得跑

方案对比(一张表)

方案 适合谁 月成本 速度 能力
OpenAI API 快速原型、复杂推理 $10-50 200+ tok/s ⭐⭐⭐⭐⭐
Claude API 长文本、代码审查 $10-50 150+ tok/s ⭐⭐⭐⭐⭐
Ollama 本地 隐私、离线、高频简单任务 硬件一次性 20-40 tok/s ⭐⭐⭐
vLLM 自部署 企业私有化、高并发 服务器成本 100+ tok/s 取决于模型
LiteLLM 代理 多模型统一入口 透传 透传 透传

换 Ollama:3 步搞定

bash 复制代码
# 1. 安装 Ollama
curl -fsSL https://ollama.com/install.sh | sh

# 2. 拉模型
ollama pull llama3.1:8b
ollama pull qwen2.5-coder:7b
python 复制代码
# 3. 改 2 行代码
from openai import AsyncOpenAI
from agents import Agent, Runner, set_default_openai_client

local_client = AsyncOpenAI(
    base_url="http://localhost:11434/v1",
    api_key="ollama",
)
set_default_openai_client(local_client, use_for_tracing=False)

agent = Agent(
    name="Local Agent",
    instructions="你是一个本地运行的助手",
    model="llama3.1:8b",
)

import asyncio
result = asyncio.run(Runner.run(agent, "用 Python 写一个二分查找"))
print(result.final_output)

就这么多。 工具定义不用改,Agent 逻辑不用改,只改模型连接。

换 Claude:通过 LiteLLM 桥接

bash 复制代码
pip install 'openai-agents[litellm]'
python 复制代码
agent = Agent(
    name="Claude Agent",
    instructions="...",
    model="litellm/anthropic/claude-sonnet-4-20250514",
)

企业级:vLLM 部署

bash 复制代码
vllm serve meta-llama/Llama-3.1-8B-Instruct \
  --host 0.0.0.0 --port 8000 \
  --max-model-len 8192

接入方式和 Ollama 一样,只是 base_url 换成你的服务器地址。

多模型统一入口:LiteLLM 代理

yaml 复制代码
# litellm_config.yaml
model_list:
  - model_name: fast
    litellm_params:
      model: openai/gpt-4o-mini
  - model_name: smart
    litellm_params:
      model: anthropic/claude-sonnet-4-20250514
  - model_name: private
    litellm_params:
      model: ollama/llama3.1:8b
      api_base: http://localhost:11434
bash 复制代码
litellm --config litellm_config.yaml --port 4000

选型决策树

markdown 复制代码
你的数据敏感吗?
├── 是 → 本地部署
│   ├── 个人用 → Ollama(一行命令搞定)
│   └── 企业用 → vLLM(高并发 + 多 GPU)
└── 不敏感 → 任务复杂吗?
    ├── 复杂推理/代码 → OpenAI / Claude API
    └── 简单/高频 → 本地 Ollama 省钱

我的实际配置 :日常用 gpt-4o-mini(便宜),复杂推理切 gpt-4o,涉及公司代码走本地 Ollama。一个月 $15 左右。


七、Q&A:你们问得最多的 7 个问题

Q1: 我已经有 31 个 Skill 了,还需要 Agent 吗?

看你的痛点:

痛点 解法
AI 不遵守 Skill 里的规则 优化 Skill 本身(不是 Agent 的问题)
每次都要手动触发 Agent(主动性)
跨会话记不住上下文 Agent + Memory
复杂任务需要多步协调 Multi-Agent
想自动化整个开发流程 必须 Agent

Skill 和 Agent 不是替代关系。 我现在的体系:31 个 Skill 定规范,3 个 Agent 做编排。Skill 是法律,Agent 是法官。

Q2: 哪个框架适合新手?

框架 学习曲线 一句话
OpenAI Agents SDK ⭐ 最低 5 行代码跑起来
CrewAI ⭐⭐ 给 Agent 一个"职位"
LangGraph ⭐⭐⭐ Agent 的 Kubernetes
AutoGen ⭐⭐⭐⭐ 学术味最重

新手路径:OpenAI Agents SDK(理解概念)→ CrewAI(多 Agent 角色分工)→ LangGraph(生产级状态机)

Q3: Agent 的 Token 成本怎么控制?

我实测一个 Research Agent 单次任务的消耗:

环节 Token 占比
System Prompt ~500 5%
工具描述 ~300 3%
工具返回结果 ~5000 50%
Agent 推理 ~3000 30%
最终输出 ~1000 10%

大头是工具返回值。 控制策略:

  1. 工具返回必须截断([:2000]
  2. 简单判断用 gpt-4o-mini,复杂推理用 gpt-4o
  3. max_turns 防无限循环
  4. 缓存重复查询

Q4: 本地模型能跑 Agent 吗?

能,但要看模型大小:

模型 内存需求 Agent 能力 适合场景
7B 8GB+ 单工具、简单 ReAct 文件操作、格式转换
13B 16GB+ 多工具、简单规划 代码生成、问答
70B 48GB+ 接近云端 复杂推理

实测体感:7B 模型跑 3 个工具的 Agent,成功率约 60%。同样任务 GPT-4o 是 95%+。

Q5: 多 Agent 之间怎么通信?

三种主流模式:

css 复制代码
模式 1:Handoff 移交(本文用的)
PM → Coder → Reviewer

模式 2:中心调度
       Orchestrator
      /     |      \
  Agent A  Agent B  Agent C

模式 3:群聊协商(AutoGen 风格)
Agent A ←→ Agent B ←→ Agent C

新手从模式 1 开始。模式 2 和 3 等你有 5+ Agent 时再考虑。

Q6: Agent 会"跑飞"怎么办?

7 道防线,按重要性排序:

  1. max_turns:最多 N 轮工具调用,超了强制停
  2. 工具白名单 :不给 rm -rf 的能力
  3. needs_approval=True:危险操作暂停等人确认
  4. Guardrails:输入/输出校验(SDK 内置)
  5. 沙箱执行:代码在隔离环境跑
  6. Tracing:每步有日志,出问题能回溯
  7. 成本熔断:token 超阈值自动终止
python 复制代码
# Guardrails 示例:拦截危险输入
from agents import Agent, input_guardrail, GuardrailFunctionOutput, RunContextWrapper

@input_guardrail
async def block_dangerous(
    ctx: RunContextWrapper, agent: Agent, input: str | list
) -> GuardrailFunctionOutput:
    text = input if isinstance(input, str) else str(input)
    dangerous = ["删除所有", "rm -rf", "drop table", "format c:"]
    is_safe = not any(word in text.lower() for word in dangerous)
    return GuardrailFunctionOutput(
        output_info={"safe": is_safe},
        tripwire_triggered=not is_safe,
    )

agent = Agent(
    name="Safe Agent",
    instructions="你是一个安全的助手",
    input_guardrails=[block_dangerous],
)

Q7: 自定义 GPTs 算 Agent 吗?

算"体验版"。它有 System Prompt(≈ Skill)+ 知识库(≈ RAG)+ 少量工具,但:

  • ❌ 没有自主循环
  • ❌ 没有持久记忆
  • ❌ 没有多 Agent 协作
  • ❌ 没有代码级控制

真正的 Agent 需要代码。自定义 GPTs 是让你体验 Agent 的感觉,但做不到 Agent 的事。


结语

上一篇,我们给 AI 写了一份岗位说明书。 这一篇,我们招了一个人。

arduino 复制代码
Skill:  "你告诉我怎么做,我就怎么做。"
Agent:  "你告诉我目标,我自己想办法。"

82 行代码,一个会搜索、会写文件、会自己判断"够不够"的 Research Agent。

再加 100 行,它有了两个同事:一个写代码,一个审代码。审查不通过,自己打回重写。

这不是科幻。这是 2026 年一个周二下午,我坐在工位上干的事。

OpenAI 做了 Agents SDK。10 万开发者已经在用了。

现在轮到你了。

从那个你每天都要手动协调 3 个步骤才能完成的任务开始。 把它交给一个 Agent。 然后看着它自己跑完。

那种感觉------就像你终于招到了一个不用催的同事。


系列回顾:


参考来源

来源 内容
OpenAI Agents SDK 官方文档 + GitHub README(Agent / Handoff / Guardrails / Tracing)
CrewAI GitHub README(Crews + Flows 双模式)
LangGraph GitHub README(状态机 / 持久执行 / Human-in-the-loop)
AutoGen Microsoft GitHub(Actor 模型 / 事件驱动)
Ollama GitHub README(本地部署 / REST API / OpenAI 兼容接口)
Anthropic Agentic Systems 官方文档
LiteLLM 多模型统一代理
相关推荐
AlienZHOU2 小时前
AI Coding 时代下,我的技术面试实践分享
前端·后端·面试
Captaincc5 小时前
AI用量v0.1.11更新发布 新增 jusage doctor 诊断指令 托盘展示token 和余额 新增 AutoClaw 支持
前端·后端·vibecoding
计算机魔术师7 小时前
德国Wiki被黑后两周,OpenAI终于把模型失控的账本摊开了
前端
kyriewen7 小时前
我让 AI 当面试官面了我一轮:第 3 个追问我就卡住了(附 10 道追问清单)
前端·面试·ai编程
IT_陈寒7 小时前
Python的GIL把我坑惨了,多线程跑得比单线程还慢
前端·人工智能·后端
65岁退休Coder8 小时前
PI Agent 开发一个生产级 Harness
后端·node.js·agent
贾伟康8 小时前
【HarmonyOS 7新能力|026】Agent Framework Kit工程封装:把接入逻辑放进可维护的分层结构
agent·harmonyos·arkts·a2a·harmonyos 7
前端snow8 小时前
ai agent --- 多agent框架之图编排引擎-langgraph
前端
竹林8188 小时前
OmniPic Studio v3.2.1 核心技术架构与全平台发版解析文档
前端·浏览器
JamesZhang800788 小时前
页面内存只涨不跌? 一次泄漏排查, 牵出 WeakMap 的诞生
前端