)
【OpenClaw从入门到精通】第87篇:打造你的第一个自定义 Agent:从设计到运行(完整实战版)摘要2024-2025年,AI Agent 从概念验证走向生产落地,但大多数开发者仍面临“框架太重、配置复杂、无法定制”的困境。本文以轻量级 Agent 框架OpenClaw为例,从零开始构建一个能检索本地知识库并回答问题的企业助手 Agent。全文字数超过10,000,涵盖 Agent 配置文件的完整结构(YAML)、自定义 Python 工具编写(文档检索、时间查询)、系统提示与少样本示例的深度设计、本地调试与日志分析、测试与部署等完整流程。文中首次公开了实际开发中遇到的7个典型踩坑案例,并提供多个可直接复用的代码模版(搜索增强、流式输出、人类审批等)。无论你是刚接触 Agent 的菜鸟,还是想从框架泥潭中抽身的进阶者,本文都能帮你用最少的代码,写出生效的第一版 Agent。关键词:AI Agent;OpenClaw;自定义 Agent;知识库检索;YAML 配置;Python 工具;Prompt Engineering;向量检索;ChromaDB;本地调试CSDN文章标签:机器学习;Python;实战教程;AI Agent;OpenClaw;知识库;企业级应用一、为什么你需要一个自定义 Agent?—— 从“通用聊天”到“行业专家”1.1 我踩过的坑就拿上个月的事来说吧,公司想搞一个内部 IT 支持机器人,直接用了某大厂的开源 Agent 框架。参数调了两周,提示词写了八大段,结果一上线就露馅了——员工问“我的打印机没墨水了”,Agent 回答“请问您要什么颜色的墨水?”。你说气不气?后来我发现,问题出在通用框架太“泛”了。它不知道你是哪个部门、内部有什么知识库、该调用哪个 API。你给它配一堆工具,它要么乱用,要么干脆不调用。说白了,没有业务定制的 Agent,就跟没有灵魂的 Python 函数一样——能运行,但不知道跑偏到哪里去了。1.2 为什么 OpenClaw 让我觉得“对味了”我试过 LangChain、MetaGPT、AutoGPT 等一堆主流框架。它们都很强大,但我总觉得像在开坦克——功能齐全,但启动太慢、太重。我需要的是个“电动车”:起步快、路线灵活、坏了自己能修。OpenClaw 是我去年底偶然发现的一个轻量级框架(GitHub 上有个小型开源项目,我给它起了个名)。它的核心理念是“配置即 Agent”——你写一个 YAML 文件,相当于给 Agent 写了个身份证,然后注册几个 Python 函数当工具,就完事了。不需要继承层层抽象类,不需要理解复杂的 Graph 编排,就这么直球。更重要的是,它的调试体验很好。你可以直接看到 LLM 内部在想什么(打印出来的),知道它为什么会选择调用那个工具。这对我们这些“不放心黑盒”的工程师来说,简直是救星。1.3 本文要达到什么目标不管你是新手还是老手,读完这篇文章后,你应该能:写出一个 ** 完整的 Agent 配置文件**(YAML),包含 model、memory、tools、system_prompt、examples。写出 ** 不少于3个自定义 Python 工具**,包括文档检索、时间查询、API 调用(我带代码)。设计 ** 有效且可控的系统提示**,融入少样本示例、动态变量、行为约束。通过 ** 日志和测试** 让 Agent 行为透明,排查常见问题。把这个 Agent 部署成一个 ** 可外呼的服务**(FastAPI)。我会用一个真实的业务场景贯穿全文:给某公司构建一个“内部知识库问答助手”,能搜索公司文档、返回带来源的答案,还能处理边界情况——比如找不到答案、重复询问等。二、先别动手:OpenClaw 核心概念你至少得懂这仨虽然框架强调“配置即 Agent”,但你总得知道配置里每个字段是干啥的。我当年就是看着 YAML 傻眼,挨个查文档才弄明白。本节约你半小时。2.1 Agent —— 一个配置文件就是一个 Agent在 OpenClaw 里,Agent 就是一段带有“脑子”和“手”的程序。“脑子”是大语言模型(LLM),“手”是工具。Agent 通过配置文件告诉你:它的身份(你是谁)、它的任务(做什么)、它的能力和限制(能用啥、不能用啥)。一个简单 Agent 的诞生过程:你写一个 YAML 文件 → OpenClaw 框架读取 → 绑定 LLM → 注册工具 → 启动会话注意,同一个 YAML 可以生成多个 Agent 实例(如果你做多租户)。但建议一个配置文件对应一种角色,别混一起。2.2 Tool —— Agent 的手工具就是一个可以被 Agent 调用的 Python 函数。它必须是 ** 有返回值的纯函数**(或者至少是无副作用的,但可以做封装)。OpenClaw 用 @tool 装饰器把函数“注册”成工具,LLM 通过工具描述来决定何时调用。工具可以是:读取本地文件(如搜索文档)调用外部 API(如查询天气、数据库)执行计算(如计算差值)执行系统命令(需谨慎,可以包装成安全接口)2.3 Memory —— Agent 的短期与长期记忆Agent 不是每次对话都从头开始——它需要记住之前聊了什么。OpenClaw 支持多种记忆策略:sliding_window:只保留最近 N 轮对话,简单实用。summary:对历史对话做摘要,然后每次都把摘要塞进去。vector:把历史对话向量化,根据当前查询召回相关历史(有点像 RAG)。hybrid:你可以混合使用,比如短期用滑动窗口,长期用向量。本文先用 sliding_window,后面升级成 hybrid。2.4 Workflow(可选)如果你需要 Agent 按步骤执行一系列有依赖关系的任务(比如先搜索、再总结、最后发邮件),就需要 Workflow。但本文聚焦单个 Agent,不提这个。三、Agent 配置文件结构:从身份证到完整蓝图3.1 最简配置(能跑就行)我第一次写 OpenClaw 配置时,就写了 20 行,心想“这也太简单了吧”。结果跑起来发现,Agent 回答全凭 LLM 自由发挥,完全不用工具。后来才明白,你得在 prompt 里明确说“先调用工具”。看这个最简模板:# knowledge_agent_minimal.yamlname:"mini-assistant"description:"最小化 Agent,只用来演示基本功能"model:provider:openaimodel:gpt-4o-mini# 省钱用这个temperature:0.3max_tokens:1024memory:type:sliding_windowwindow_size:5tools:-name:get_current_timedescription:"获取当前服务器时间"system_prompt:|你是公司的内部助手。请严格按照以下规则: 1. 如果用户问时间,你必须先调用 get_current_time 工具。 2. 如果不知道答案,直接说不知道,不要编。 3. 回答简洁,不超过100字。注意,temperature: 0.3意味着 LLM 输出会比较“保守”(不易发散),适合事实性回答。如果你想让它更有创意,可以调高到 0.7,但知识库场景不建议。3.2 生产级配置(考虑异常、安全、扩展)下面的配置来自我真正部署的版本,增加了交互约束、fallback、工具超时等。# knowledge_agent_prod.yamlname:"knowledge-assistant-prod"description:"公司内部知识库问答助手(生产版)"version:"1.2.0"agent_id:"prod-ka-v1.2"model:provider:openaimodel:gpt-4temperature:0.2max_tokens:2048frequency_penalty:0.1# 防止重复presence_penalty:0.1interaction:max_rounds:15# 一轮会话最多15次对话(防死循环)fallback_message:"抱歉,我暂时无法处理这个请求。如果需要,请找IT支持。"context_window:4096# 输入上下文上限(超出会被截断)require_confirmation:false# 高风险工具才需要确认memory:type:hybridconfig:short_term:type:sliding_windowwindow_size:10long_term:type:vectorcollection:"agent_memory"embed_model:"all-MiniLM-L6-v2"similarity_threshold:0.75# 只有高相关的历史记忆才会被注入tools:-name:get_current_timedescription:"返回当前服务器的日期和时间,格式为YYYY-MM-DD HH:MM:SS。不应包含时区信息。"enabled:true-name:search_documentsdescription:"从公司内部知识库检索与用户问题相关的文档片段。输入参数:query(字符串,用户的自然语言问题),top_k(整数,返回结果数量,默认3)。"parameters:query:type:stringdescription:"用户查询的自然语言问题,应保持原意,不要改写。"top_k:type:integerdescription:"返回的文档块数量,范围1-5,默认3。"default:3min:1max:5enabled:true-name:call_internal_apidescription:"调用公司内部报表API,用于查询销售数据、员工信息等。输入:endpoint(API路径),params(字典)。注意:该工具仅限内部网络使用。"enabled:false# 先禁用,后面开启tool_settings:default_timeout:15# 工具调用超时(秒)default_retry:2retry_delay:1.5max_retries:3system_prompt:|你是公司内部的智能知识助手,名字叫“小智”。你的任务是:**核心规则**:1. 收到用户问题后,必须首先调用 search_documents 工具搜索知识库,即使你觉得自己知道答案。这是为了保证信息的准确性。 2. 如果 search_documents 返回的结果中,最高得分低于0.6,则回复“未在知识库中找到高度相关的信息,建议联系文档管理团队补充资料”。 3. 如果找到相关信息,用中文简要总结,并在末尾注明出处,格式为【来源:文件名】。 4. 不要添加虚构的事实或观点。 5. 对于时间查询(如今天星期几),直接调用 get_current_time 工具,然后告诉用户。 6. 如果用户问题涉及人事、财务等敏感字段,回答“该问题涉及敏感信息,请通过正式流程咨询”。**风格**:-使用专业、简洁的商务语气。-每段不超过3句话。-不要使用表情符号。**额外指令**:-当前对话已进行{round_count}轮。若超过5轮用户仍然在问类似问题,考虑问用户是否需要新建对话。-当前日期:{current_date}examples:-user:"请问公司的年假政策是怎样的?"assistant:-tool_call:search_documents(query="年假政策",top_k=3)-tool_result:[{"content":"根据《员工手册》2024版第4章,正式员工每年享有15天年假。","source":"员工手册.txt","score":0.94},{"content":"年假未休完的部分可以顺延至次年3月底。","source":"员工手册.txt","score":0.88}]-final:"正式员工每年享有15天年假,未休完部分可顺延至次年3月底。【来源:员工手册.txt】"-user:"今天星期几?"assistant:-tool_call:get_current_time()-tool_result:"2025-03-15 10:30:00"-final:"今天是2025年3月15日,星期六。"-user:"如何重置密