ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

开发 AI Agent 的三条第一性原理:从 Prompt 到 Human-in-the-loop 的工程实践

开发 AI Agent 的三条第一性原理:从 Prompt 到 Human-in-the-loop 的工程实践 1. 为什么你的 Agent 总在第三步开始跑偏先说一个我观察到的现象大部分 Agent 项目不是死在模型能力上而是死在“任务定义”这一步。你给它一句“帮我分析一下这个项目”它返回的东西看起来像模像样但你要的其实是“找出这个仓库里所有未处理的 TODO 并按优先级排序”。这两件事之间的差距就是 Agent 跑偏的根源。AI Agent 的本质是一个“在不确定环境中做决策的执行体”。它和普通函数调用的区别在于函数调用你给什么参数它就返回什么结果而 Agent 需要自己判断“我现在该做什么”“做到什么程度算完”“下一步该调哪个工具”。这三个判断只要有一个模糊它就会开始自由发挥。我试过用同一个模型跑两个任务一个是“帮我优化这段代码”另一个是“找出这段代码中所有时间复杂度高于 O(n²) 的循环给出优化方案并标注改动行号”。前者返回了一堆泛泛而谈的建议后者直接给出了可用的 diff。模型没变变的是任务定义的精度。所以第一条第一性原理就是把模糊意图翻译成结构化契约。你需要显式定义五个维度——目标解决什么问题、边界能做什么不能做什么、标准什么叫合格、进度当前在哪一步、终止条件什么时候停。这五个维度不一定要写在 Prompt 里但必须存在于你的系统设计中。Human-in-the-loop 不是“加个人工审核按钮”那么简单。它的核心是在 Agent 的决策链路上设置“不可逆操作前的确认点”。比如 Agent 要执行数据库写入、要发送邮件、要调用支付接口这些操作必须经过人工确认。而查询类、计算类操作可以自动放行。这个判断逻辑本身也要写进系统不能靠 Agent 自己“觉得该不该问”。工具链集成则是把 Agent 从“聊天机器人”变成“执行体”的关键。一个只会输出文本的 Agent 价值有限能调用搜索、读写文件、执行脚本、查询数据库的 Agent 才是生产力。但工具越多Agent 选错工具的概率越大。所以工具描述必须精确到“什么场景下用这个工具、输入格式是什么、返回什么、什么情况下不要用”。这三条原则合在一起就是一个可调试、可干预、可复现的 Agent 工作流。下面我会从环境准备开始一步步给出可复制的配置和验证步骤。2. TaoToken 接入准备统一模型入口与 Key 管理在搭 Agent 之前你需要一个稳定的模型调用入口。我选择用 TaoToken 作为统一接入层原因是它兼容 OpenAI 风格的接口格式同时支持多个模型 ID 的切换这样你在调试不同 Agent 角色时不需要改代码只改配置就行。先明确三个核心信息Base URLhttps://taotoken.net/apiAPI Key在控制台创建格式通常是sk-开头Model ID根据你用的模型填写比如gpt-4o、claude-3-5-sonnet等如果你用的是 Claude Code 这类工具需要在配置文件中指定 Anthropic 兼容的端点。TaoToken 提供了对应的接入文档路径在/doc下可以找到。对于 Cline、Cursor 这类编辑器插件Base URL 填https://taotoken.net/apiKey 填你创建的 API KeyModel ID 按实际模型填。这里有一个容易踩的坑很多人把 Base URL 写成https://taotoken.net/api/v1结果请求 404。正确的做法是 Base URL 只写到/api具体的/v1/chat/completions由 SDK 或工具自己拼接。如果你用的是 OpenAI 官方 SDK设置base_urlhttps://taotoken.net/api即可。另一个坑是 Key 的权限范围。建议为 Agent 项目单独创建一个 Key不要和日常对话混用。这样你可以单独监控这个 Key 的调用量出问题时也容易定位。创建 Key 的入口在控制台的 API Keys 页面。对于需要长期跑 Agent 任务的场景可以考虑 Coding Plan它适合需要持续调用模型进行代码生成、审查、重构的工作流。如果你只是验证模型效果用模型对话页面直接测试就行。环境变量建议这样设置export TAOTOKEN_BASE_URLhttps://taotoken.net/api export TAOTOKEN_API_KEYsk-你的Key export TAOTOKEN_MODELgpt-4oWindows 下用set或$env:对应设置。设置完之后用curl验证一下连通性curl -s $TAOTOKEN_BASE_URL/v1/chat/completions \ -H Authorization: Bearer $TAOTOKEN_API_KEY \ -H Content-Type: application/json \ -d { model: $TAOTOKEN_MODEL, messages: [{role: user, content: ping}], max_tokens: 10 }如果返回 JSON 里有choices字段说明接入正常。如果返回 401检查 Key 是否复制完整如果返回local proxy failed检查你的网络环境是否阻止了对taotoken.net的访问。3. 可复制的 Agent 配置模板Prompt HITL 工具链这一节给出一个完整的 Agent 配置模板你可以直接复制到项目里用。模板分为三部分系统 Prompt、Human-in-the-loop 规则、工具链定义。3.1 系统 Prompt 模板{ role: system, content: 你是一个任务执行 Agent。你的工作流程如下\n\n1. 解析用户输入提取目标、边界、验收标准、当前进度、终止条件。\n2. 如果以上五项中有任何一项不明确先向用户提问确认不要自行假设。\n3. 确认后输出执行计划格式为步骤编号 | 操作 | 预期结果 | 是否需要人工确认。\n4. 按计划逐步执行。每完成一步输出当前步骤 | 实际结果 | 是否与预期一致 | 下一步。\n5. 遇到以下情况必须暂停并请求人工确认涉及数据写入、删除、发送外部请求、调用支付接口。\n6. 如果连续两次执行结果与预期不一致停止并输出错误报告。\n\n输出格式要求所有中间结果用 JSON 格式返回字段包括 step、action、result、need_human、next。 }这个 Prompt 的关键在于把“五要素确认”和“人工确认触发条件”写死了。Agent 不需要自己判断“该不该问”规则已经告诉它什么情况下必须问。3.2 Human-in-the-loop 配置HITL 的实现方式取决于你用的框架。如果你用的是 LangChain 或类似框架可以用 callback 机制拦截工具调用。下面是一个简化的 Python 示例from langchain.agents import AgentExecutor from langchain.tools import tool SENSITIVE_ACTIONS [write_file, delete_record, send_email, execute_payment] def hitl_callback(action, input_data): if action in SENSITIVE_ACTIONS: print(f[HITL] Agent 请求执行敏感操作: {action}) print(f[HITL] 输入数据: {input_data}) confirm input(是否允许(y/n): ) return confirm.lower() y return True tool def write_file(path: str, content: str) - str: 写入文件。需要人工确认。 if not hitl_callback(write_file, {path: path, content: content}): return 操作被人工拒绝 with open(path, w) as f: f.write(content) return f已写入 {path}如果你用的是 Cline 或 Claude Code 这类工具HITL 通常以“确认对话框”的形式内置了。你需要在设置里开启“执行前确认”选项并配置哪些操作需要确认。对于 Codex 的auth.json配置需要确保approval_mode设置为suggest或auto-edit而不是full-auto。3.3 工具链定义模板工具链的定义要精确到“什么场景用、输入什么、返回什么、什么情况下不用”。下面是一个 TOML 格式的工具定义示例[[tools]] name search_web description 搜索互联网获取实时信息。仅在需要最新数据时使用。不要用于查询本地文件。 input_schema { query string, max_results integer } output_schema { results array of {title, url, snippet} } when_to_use 用户问题涉及实时信息、新闻、价格、天气等 when_not_to_use 用户问题涉及本地代码、本地文件、已缓存的文档 [[tools]] name read_file description 读取本地文件内容。支持 txt、md、json、py 等文本格式。 input_schema { path string } output_schema { content string, size integer } when_to_use 需要查看本地文件内容时 when_not_to_use 文件路径不存在或没有读取权限时 [[tools]] name execute_script description 执行本地脚本。仅支持 Python 和 Bash。执行前需要人工确认。 input_schema { language string, code string } output_schema { stdout string, stderr string, exit_code integer } when_to_use 需要计算、转换数据、调用本地命令时 when_not_to_use 涉及系统级操作、网络请求、文件删除时这个模板的好处是Agent 在选择工具时有明确的判断依据不会出现“该用搜索却去读文件”的情况。同时when_not_to_use字段能有效减少误调用。把这三部分组合起来你就得到了一个可调试的 Agent 工作流。接下来验证它是否能跑通。4. 验证请求与成功结果从 ping 到完整任务执行配置写完之后不要直接上复杂任务。先用一个最小可验证请求确认链路通畅再逐步增加复杂度。4.1 最小验证单轮对话curl -s $TAOTOKEN_BASE_URL/v1/chat/completions \ -H Authorization: Bearer $TAOTOKEN_API_KEY \ -H Content-Type: application/json \ -d { model: $TAOTOKEN_MODEL, messages: [ {role: system, content: 你是一个测试助手。只回复 OK。}, {role: user, content: 测试连接} ], max_tokens: 20 }预期返回{ choices: [ { message: { role: assistant, content: OK } } ] }如果返回内容不是 OK检查 system prompt 是否被正确传递。有些 SDK 会把 system 消息放在单独字段而不是 messages 数组里。4.2 结构化输出验证Agent 的核心能力之一是输出结构化数据。用下面的请求验证模型是否能按 JSON 格式返回curl -s $TAOTOKEN_BASE_URL/v1/chat/completions \ -H Authorization: Bearer $TAOTOKEN_API_KEY \ -H Content-Type: application/json \ -d { model: $TAOTOKEN_MODEL, messages: [ {role: system, content: 你是一个任务解析器。将用户输入解析为 JSON字段包括goal、boundary、criteria、progress、stop_condition。只输出 JSON不要其他内容。}, {role: user, content: 帮我分析一下这个项目的代码质量} ], max_tokens: 500 }预期返回类似{ goal: 分析项目代码质量, boundary: 仅分析代码层面不涉及架构设计, criteria: 输出可量化的质量指标, progress: 初始阶段, stop_condition: 输出完整分析报告 }如果模型返回了额外文字说明 system prompt 里的“只输出 JSON”约束不够强。可以在末尾加一句“如果输出非 JSON 内容任务视为失败”。4.3 完整任务执行验证用一个真实的小任务验证整个工作流让 Agent 读取一个本地文件统计行数然后写入结果。import os import json from openai import OpenAI client OpenAI( base_urlos.environ[TAOTOKEN_BASE_URL], api_keyos.environ[TAOTOKEN_API_KEY] ) def run_agent(task: str): messages [ {role: system, content: open(agent_prompt.txt).read()}, {role: user, content: task} ] response client.chat.completions.create( modelos.environ[TAOTOKEN_MODEL], messagesmessages, max_tokens1000 ) return response.choices[0].message.content result run_agent(读取 ./test.txt 文件统计行数将结果写入 ./result.json) print(result)预期输出是一个 JSON包含 step、action、result、need_human、next 字段。如果 need_human 为 true说明 Agent 识别到了敏感操作并请求确认。成功跑通这个流程后你就有了一个可调试、可干预的 Agent 基础框架。接下来处理常见错误。5. 常见报错排查401、local proxy failed、reading choices、OAuth这一节列出我在调试 Agent 时遇到的高频错误和对应解法。5.1 401 Unauthorized现象请求返回{error: {message: Invalid API key, type: invalid_request_error}}。原因Key 错误、Key 过期、Key 权限不足、或者请求头格式不对。排查步骤检查Authorization头是否写成Bearer sk-xxx注意 Bearer 和 Key 之间有一个空格。检查 Key 是否复制完整有没有多余空格或换行。在控制台确认这个 Key 是否被禁用或删除。如果用的是环境变量用echo $TAOTOKEN_API_KEY确认值是否正确。5.2 local proxy failed现象请求返回local proxy failed或连接超时。原因网络环境无法访问taotoken.net或者本地代理配置冲突。排查步骤用curl -v https://taotoken.net/api检查是否能建立连接。检查系统代理设置确保没有残留的代理配置干扰。如果公司网络有防火墙确认taotoken.net在允许列表中。尝试用ping taotoken.net检查 DNS 解析是否正常。5.3 reading choices 报错现象代码报KeyError: choices或TypeError: NoneType object is not subscriptable。原因API 返回的 JSON 结构不符合预期通常是请求参数错误导致返回了错误信息而不是正常响应。排查步骤打印完整的 response 内容看实际返回了什么。检查model字段是否拼写正确有些模型 ID 区分大小写。检查messages数组是否为空或者 role 字段是否合法。如果返回的是流式响应需要用streamTrue并逐块解析。5.4 OAuth 相关错误现象使用 Claude Code 或类似工具时提示 OAuth 认证失败。原因工具默认走 OAuth 流程但你的环境需要走 API Key 认证。排查步骤在工具配置中找到认证方式设置切换为 API Key 模式。对于 Claude Code检查~/.claude/config.json中的apiKey字段是否设置正确。对于 Codex检查auth.json中的api_key字段确保没有残留的 OAuth token。如果工具同时支持两种认证方式明确指定使用 API Key。5.5 工具调用死循环现象Agent 反复调用同一个工具不输出最终结果。原因终止条件不明确或者工具返回结果不符合 Agent 预期。排查步骤在 system prompt 中明确“连续两次结果不一致时停止”。检查工具返回格式是否和output_schema一致。设置最大迭代次数比如max_iterations10超过就强制停止。在 HITL 回调中增加“重复调用检测”同一工具连续调用超过 3 次就请求人工介入。这些错误覆盖了大部分调试场景。如果遇到其他报错优先检查请求参数和返回结构大部分问题都能定位到具体字段。6. 从可跑通到可运营Agent 工程的下一步跑通一个 Agent 不难难的是让它稳定运行。我自己的经验是前 10 次调用可能都正常第 11 次开始出现各种边界情况。所以你需要把 Agent 当成一个需要持续运营的系统而不是一次性的脚本。第一件事是 Prompt 版本化。把每次修改的 system prompt 存下来标注修改原因和效果。这样出问题时可以快速回滚。可以用 Git 管理也可以用简单的文件命名规则比如agent_prompt_v1.txt、agent_prompt_v2.txt。第二件事是日志记录。每次 Agent 调用都记录输入、输出、工具调用序列、耗时、token 消耗。这些数据能帮你发现“哪类任务容易失败”“哪个工具调用最频繁”“哪个步骤耗时最长”。有了这些数据优化才有方向。第三件事是渐进式确认。不要一次性把整个任务丢给 Agent而是分阶段确认。比如先确认任务解析结果再确认执行计划最后确认执行结果。每个阶段都可以人工干预避免一步错步步错。第四件事是错误防护层。至少加两个机制一个是审核 Agent对执行结果做二次校验另一个是自动验证用规则检查输出是否符合预期格式。这两个机制能拦住大部分低级错误。如果你需要长期跑 Agent 任务可以考虑用 Coding Plan 来管理模型调用配额和成本。对于需要频繁调试的场景模型对话页面可以快速测试不同 Prompt 的效果。API Key 的管理在控制台的 API Keys 页面建议为每个 Agent 项目单独创建 Key。最后说一个我踩过的坑不要试图用一个超级 Prompt 解决所有问题。我一开始把任务解析、执行、校验、总结全写在一个 Prompt 里结果 Agent 经常在“执行”阶段忘记“校验”规则。后来拆成四个独立的 Agent 角色每个角色只负责一件事稳定性大幅提升。系统能力永远大于单模型能力这是第三条第一性原理的实践含义。
返回列表