ingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;display: table;padding: 0px 0.2em;color: rgb(255, 255, 255);background: rgb(85, 201, 234);">引言ingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: 14px;letter-spacing: 0.1em;color: rgb(63, 63, 63);">我在过去一年里构建了十几个不同类型的 Agent 应用。期间踩了无数坑:Agent "失忆"、工具调用失败、提示词效果不稳定等等问题ingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: 14px;letter-spacing: 0.1em;color: rgb(63, 63, 63);">直到我看到了 HumanLayer 团队总结的"12 条构建可靠 AI 应用的实践原则",很多困扰我的问题终于有了系统性的解决方案。它们可能会让你的 Agent 能力提升 10 倍。ingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;display: table;padding: 0px 0.2em;color: rgb(255, 255, 255);background: rgb(85, 201, 234);">12 条实践原则ingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;padding-left: 8px;color: rgb(63, 63, 63);">1. 使用自然语言调用工具ingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: 14px;letter-spacing: 0.1em;color: rgb(63, 63, 63);">Agent 构建最常见的模式就是将自然语言转成ingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: inherit;color: rgb(85, 201, 234);">结构化的工具调用。ingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: 14px;letter-spacing: 0.1em;color: rgb(63, 63, 63);">想象一下,我们对 AI 说ingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-feature-settings: normal;font-variation-settings: normal;font-size: 12.6px;text-align: left;line-height: 1.75;color: rgb(221, 17, 68);background: rgba(27, 31, 35, 0.05);padding: 3px 5px;border-radius: 4px;">创建 750 美元的付款给小明的链接,用于赞助二月份聚会的费用。 LLMs 会转成结构化的数据ingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-feature-settings: normal;font-variation-settings: normal;font-size: 12.6px;margin: 10px 8px;color: rgb(201, 209, 217);background: rgb(13, 17, 23);text-align: left;line-height: 1.5;overflow-x: auto;border-radius: 8px;padding: 0px !important;">{ "function":{ "name":"create_payment_link", "parameters":{ "amount":750, "customer":"cust_128934ddasf9", "product":"prod_8675309", "price":"prc_09874329fds", "quantity":1, "memo":"赞助二月份聚会的付款链接" } } }这就是 Agent 构建的核心:自然语言到结构化调用的转换。 2. 定义自己的提示词我们应该使用自己的提示词,而不是让框架自己来包装提示词。 很多框架提供了“黑盒”方法: agent = Agent( role="...", goal="...", personality="...", tools=[tool1, tool2, tool3] )
task = Task( instructions="...", expected_output=OutputModel )
result = agent.run(task)
这种方式适合入门,但是很难调整,你根本不知道框架背后到底在说什么。 我们应该把提示词作为一等公民来对待,下面是一段比较粗糙但直观的示例 # 系统提示词 你是一名【主要功能】的【角色】。
你的执行流程是 - 【步骤1】 - 【步骤2】
你可以使用【Tool1】【Tool2】
# 用户提示词
【用户的输入】
使用自己的提示词带来的好处: - •完全控制:准确编写提示词,极大的灵活性,可以自由尝试和调整
3. 定义自己的上下文和 LLMs 聊天,本质上就是在说“这是目前的情况,下一步要做什么”。 这是目前的情况就是我们的上下文。通常包括:
 大多数框架会生成标准格式的上下文: [ { "role":"system", "content":"你是一个乐于助人的助手..." }, { "role":"user", "content":"你能部署后端吗?" }, { "role":"assistant", "content":null, "tool_calls":[ { "id":"1", "name":"list_git_tags", "arguments":"{}" } ] }, { "role":"tool", "name":"list_git_tags", "content":"{\"tags\": [{\"name\": \"v1.2.3\", \"commit\": \"abc123\", \"date\": \"2024-03-15T10:00:00Z\"}.....]}", "tool_call_id":"1" } ]
但你可以设计更高效的自定义格式,最大化模型性能。(还是那句话,完全自己控制,获得极大的灵活性) [ { "role":"system", "content":"你是一个乐于助人的助手..." }, { "role":"user", "content":| 以下是截至目前发生的所有事件:
<slack_message> From alex Channel:#deployments Text:Can you deploy the backend? </slack_message>
<list_git_tags> intent:"list_git_tags" </list_git_tags>
<list_git_tags_result> tags: - name:"v1.2.3" commit:"abc123" date:"2024-03-15T10:00:00Z" - name:"v1.2.2" commit:"def456" date:"2024-03-14T15:30:00Z" - name:"v1.2.1" commit:"ghi789" date:"2024-03-13T09:15:00Z" </list_git_tags_result>
下一步是什么? } ]
自定义的格式可以更节省 Token、更有利于模型注意力分配的方式传递信息,从而提升性能。你可以使用更适合你应用的格式,而不是局限于 XML。 自定义格式的核心优势: - •错误处理:有助于 LLMs 理解错误从中恢复,也可以在后续动作隐藏错误信息(避免冗余)
- •节省Token:优化上下文可以节省 Token,提高 LLMs 的理解
 4. 工具调用只是结构化的输出很多人把工具调用想得很复杂,其实就三步: - • LLMs 输出结构化的内容(可能是 JSON,也可以是其他结构化格式)
- • 执行确定性的代码(本地命令执行、API 调用等等)
输出格式不一定要是JSON。,JSON 格式太严格,LLM 可能输出语法有问题的 JSON,其他任何结构化(XML、YAML等)的我们能够解析的格式都可以。 拓展阅读:Schema-Aligned Parsing[1]、When should I use function calling, structured outputs or JSON mode?[2] 5. 统一执行状态和业务状态传统软件开发习惯分离执行状态(当前步骤、等待、重试)和业务状态(数据、消息)。但在AI应用中,这样做可能过度复杂。LLM可以通过上下文自动推断所有状态。 统一管理的好处: - •灵活性:只需定义新的事件类型,就能轻松扩展 Agent 的状态和能力
- •可恢复性:只需加载历史记录即可从任意节点恢复运行
- •可分叉:可以随时复制部分历史记录到一个新的上下文中,轻松创建分支
- •人机界面与可观测性:将事件历史转换为可读的格式(如 Markdown)或富文本 UI 界面变得非常简单
6. 实现启动、暂停、恢复把AI Agent想象成普通程序,提供标准的控制接口: 这些能力特别适用于: 比如,Agent 想执行某个脚本时,可以暂停让人类检查修改,然后继续执行。 |