AI Agent工程落地七要素与决策点实战指南

发布时间:2026/10/8 16:31:00
AI Agent工程落地七要素与决策点实战指南 1. 项目概述为什么“解构 AI Agent”这件事比你想象中更紧迫最近三个月我帮六家不同行业的客户落地 AI Agent 项目从电商客服自动兜底流程到制造业设备故障的多模态诊断链路再到律所合同条款的实时交叉验证系统。每次开场白都一样“我们想做个 Agent但不知道从哪下手。”——结果无一例外第一周全卡在“到底什么是 Agent”的认知撕裂上。有人把它当成高级版 Chatbot调个 API 就开干有人翻遍论文堆出二十层抽象架构图却连一个能跑通的工具调用循环都搭不出来更多人则困在“LLM 是大脑那手脚在哪怎么教它不瞎动”这种具体问题里反复打转。这恰恰印证了标题里那个被严重低估的关键词工程实现。不是理论推演不是概念炫技而是让一个智能体在真实服务器、真实数据库、真实用户请求流里稳定、可测、可维护地跑起来。所谓“七要素”不是学术分类法而是我在产线踩坑后画出的七个必须显式声明、必须独立测试、必须版本管控的模块切片所谓“七个决策点”也不是 checklist而是每次写完一行代码、配完一个 YAML、改完一个 prompt 后我必须拍着桌子问自己的问题“这里如果失败系统是静默崩塌还是优雅降级日志能定位到第几行重试策略谁来定超时阈值怎么算出来的”比如上周一个金融客户要求“自动核验开户材料真实性”表面看是 OCRLLM规则引擎三件套实际落地时卡在第三个决策点当 LLM 对身份证有效期返回“不确定”时系统该触发人工复核队列还是调用公安接口二次验证这个选择直接决定整个链路的 SLA 是 99.9% 还是 95%。所以这篇文章不讲“Agent 是什么”只讲“怎么把它焊死在生产环境里”。适合正在写第一个 Agent 的工程师、带团队做技术选型的 TL、以及被老板追问“什么时候上线”的产品经理。如果你刚读完 LangChain 文档还觉得云里雾里或者调试 Tool Calling 时发现错误日志全是 LLM 的胡言乱语那接下来的内容就是你缺的那张施工图纸。2. 七要素拆解每个模块都是可插拔、可监控、可替换的独立单元2.1 要素一目标定义器Goal Decomposer——不是写一句自然语言需求而是生成可执行的原子任务树很多人以为 Agent 的“目标”就是用户输入的一句话比如“帮我查下北京今天空气质量再订一张明天去上海的机票”。但工程上这句话必须被拆解成带依赖关系、带约束条件、带失败回滚路径的结构化任务树。我见过最典型的反例是某 SaaS 公司把用户提问直接喂给 LLM让它自己决定下一步——结果 LLM 在“订机票”环节突然开始分析航空公司的碳排放数据彻底偏离主线。真正的目标定义器必须做三件事第一语法解析识别显性指令“查”“订”“对比”和隐性约束“今天”“明天”“北京”“上海”。我们用正则轻量 NER 模型预处理而非依赖 LLM因为后者对时间/地点等实体识别不稳定。例如“下周三下午三点前”会被标准化为 ISO8601 时间戳 时区偏移避免 LLM 自由发挥。第二任务拓扑构建将目标分解为 DAG有向无环图节点是原子任务如“调用天气 API”“解析航班列表”边是依赖关系“订机票”必须等“查天气”完成。关键在于标注每个节点的执行策略串行必须等前序完成、并行可并发调用多个天气源、条件分支若天气指数150则跳过订票。第三失败熔断注入为每个节点预设 fallback 动作。比如“调用天气 API 失败”时是重试 3 次降级到缓存数据还是直接终止整个流程并通知用户这个逻辑不能写在 LLM 的 system prompt 里而要硬编码进目标定义器的配置表中。我们用 YAML 定义任务模板其中fallback: {type: cache, key: beijing_air_quality_24h}这样的字段确保运维人员能直接修改无需动代码。实测下来把目标拆解从 LLM 驱动改为规则驱动后任务成功率从 72% 提升到 98.3%且平均响应时间降低 400ms——因为少了 LLM 的推理延迟。2.2 要素二状态管理器State Manager——拒绝“LLM 记忆即一切”的幻觉用分层存储保真相几乎所有初学者都掉进同一个坑相信 LLM 的上下文窗口能记住所有交互细节。结果在复杂流程中Agent 忘记用户刚否决的酒店选项或混淆两个并行任务的中间结果。工程上状态管理器必须是分层、分区、带版本的独立服务。我们采用三级存储架构L1 瞬时状态存在内存中仅保留当前任务链路的必要上下文如“当前在订机票步骤已选定航班 CA123”。生命周期与单次请求绑定请求结束即销毁。这是唯一允许 LLM 直接读写的层但严格限制 token 数量≤512。L2 持久状态存入 Redis按 session_id 分区存储跨步骤的共享数据如“用户偏好无烟房”“预算上限 800 元”。关键设计是状态快照机制每次任务节点切换时自动保存当前 L2 状态的 SHA256 哈希值。当流程异常中断恢复时先校验哈希若不匹配则触发状态修复流程——比如对比数据库中订单表的实际状态反向修正 Redis 中的“已支付”标记。L3 归档状态写入 PostgreSQL记录完整操作日志含 LLM 输入输出、工具调用参数、耗时、错误码。这不是为了“审计”而是为可重现性服务。当用户投诉“Agent 把我的机票订错了”我们能用归档 ID 精确还原当时所有输入甚至用相同 prompt 和模型权重在测试环境重放整个链路。提示千万别把敏感信息如身份证号、银行卡号存进 L1 或 L2。我们在状态管理器入口强制做 PII个人身份信息扫描命中即脱敏为哈希值并在 L3 归档中单独加密存储原始数据。这不仅是安全要求更是调试刚需——你总不想在日志里看到一长串明文银行卡号吧2.3 要素三工具协调器Tool Orchestrator——不是简单封装 API而是构建带契约、带熔断、带可观测性的工具网络“引入工具类”是热搜词但多数人只做到第一步把天气 API 封装成一个函数。真正的工具协调器要解决三个工程问题契约一致性、故障隔离性、调用可观测性。首先契约定义。每个工具必须提供 OpenAPI 3.0 格式的规范文件明确输入参数类型如date: string, format: YYYY-MM-DD、输出结构{code: 200, data: {aqi: integer, level: string}}、错误码映射404 - CITY_NOT_FOUND。LLM 不会自己猜参数格式我们用 JSON Schema 生成工具描述文本喂给 LLM 时附带“请严格按以下字段名和类型调用”的指令。实测发现契约清晰后工具调用失败率从 35% 降至 8%。其次故障隔离。工具调用必须运行在独立进程或容器中与主 Agent 进程解耦。我们用 Rust 编写轻量级工具网关基于 Tokio每个工具注册为一个 HTTP endpoint主进程通过 gRPC 调用。好处是当天气 API 响应超时不会拖垮整个 Agent当某个工具崩溃网关自动重启它且不影响其他工具。更重要的是网关内置熔断器——若某工具连续 5 次超时自动切换到备用源如从高德天气切到心知天气无需 LLM 参与决策。最后可观测性埋点。每次工具调用网关自动生成 trace_id记录调用时间、参数摘要脱敏后、响应时间、HTTP 状态码、LLM 解析的工具名。这些数据实时推送到 Prometheus我们设置告警规则若“订机票工具”的 P95 延迟 2s或错误率突增 20%立即通知值班工程师。这才是真正的“工具可控”而不是靠 LLM 的口头汇报。2.4 要素四记忆检索器Memory Retriever——不是塞满向量库而是按场景精度分级召回“记忆”常被神化为 Agent 的核心能力但工程上它只是个带策略的数据库查询服务。我们绝不把所有聊天记录扔进一个向量库而是按使用场景分三层短期记忆Short-term存于内存仅保留当前会话最近 5 轮对话的 embedding用于快速判断用户意图是否突变如从“查天气”突然跳到“帮我写辞职信”。召回时用余弦相似度阈值设为 0.75低于此值即判定为新话题。长期记忆Long-term存于专用向量库Weaviate但只索引结构化事实如“用户张三的常住地址是北京市朝阳区XX大厦”而非整段对话。关键创新是记忆标签系统每条记忆打上source: user_profile、confidence: 0.92、valid_until: 2025-12-31等标签。LLM 请求记忆时必须指定标签过滤条件如“召回所有 confidence0.8 的 user_profile 记忆”避免噪声干扰。外部知识External对接企业知识库Confluence/Notion但检索前先做领域过滤。比如用户问“报销流程”检索器先调用一个轻量分类模型判断问题属于“财务”域再只搜索财务相关文档而非全库扫描。这使召回准确率提升 60%且避免 LLM 被无关文档误导。注意记忆检索结果必须附带来源溯源。每条召回内容标注doc_id: FIN-2024-001、page: 3、snippet: 员工需在费用发生后30日内提交...。LLM 生成答案时必须引用这些溯源信息方便用户核查。我们甚至开发了“溯源验证”功能用户点击答案中的[1]直接跳转到原始文档对应位置。2.5 要素五规划执行器Plan Executor——不是让 LLM 自由发挥而是用确定性流程控制不确定性“规划”是 Agent 最易失控的环节。很多方案让 LLM 输出 JSON 格式的 plan再解析执行。但 LLM 会随机生成不存在的工具名、漏掉必要步骤、甚至嵌套无限循环。我们的规划执行器采用混合模式确定性骨架预先定义 12 种高频业务流程的执行骨架如“订机票”骨架包含1. 解析出发/到达地 → 2. 调用航班查询 API → 3. 展示结果供选择 → 4. 调用预订 API → 5. 发送确认短信。每个骨架是硬编码的状态机节点间流转条件明确如“步骤2成功且返回航班数0”才进入步骤3。LLM 填充层LLM 只负责填充骨架中的变量值和分支选择。例如在“展示结果”节点LLM 只需从 API 返回的 10 个航班中按用户偏好价格优先/时间优先排序并返回 top3 的 ID 列表它不能新增“比较航空公司准点率”这个步骤。执行监控每个骨架节点执行时启动独立 watchdog 进程监控超时如航班查询 3s、异常返回HTTP 500、数据空值。一旦触发立即按预设策略处理重试/降级/报错并记录到状态管理器。这样即使 LLM 在填充层出错如返回了不存在的航班 ID也不会破坏整个流程的稳定性。实测表明混合模式下流程中断率比纯 LLM 规划低 89%。2.6 要素六反思评估器Reflection Evaluator——不是事后总结而是实时干预的“刹车系统”“反思”常被理解为 LLM 对自己输出的自我批评但这在工程上毫无意义——它无法改变已发生的错误。我们的反思评估器是实时、可干预、带动作的监控模块。它在三个关键点介入工具调用前检查 LLM 生成的工具调用参数是否符合契约。例如天气 API 要求city参数为城市拼音但 LLM 输出了中文“北京”评估器自动转换并记录warning: city param converted from 北京 to beijing。工具响应后解析返回数据是否符合预期结构。若航班 API 返回{error: timeout}评估器不交给 LLM 解释而是直接触发熔断调用备用 API。最终输出前对 LLM 生成的答案做事实性校验。例如当答案声称“上海今天空气质量优”评估器会并行调用天气 API 验证若不符则插入纠错声明“根据实时数据上海 AQI 为 128轻度污染建议减少户外活动。”这个模块的核心价值在于把 LLM 的不可控性转化为可监控、可拦截、可补偿的确定性事件。它不追求让 LLM 更聪明而是确保它犯错时系统能第一时间兜住。2.7 要素七安全守门员Safety Gatekeeper——不是加一层过滤而是贯穿全流程的防御纵深“agent安全”是热搜词但多数方案只在输入输出加关键词过滤形同虚设。我们的安全守门员是七层防御体系覆盖从请求接入到结果返回的全链路L1 接入层Nginx 配置 IP 白名单和 QPS 限流防暴力探测。L2 输入层用规则引擎Drools检测恶意 payload如 Base64 编码的 shell 命令、SQL 注入特征。L3 工具层工具网关强制校验所有出参禁止返回system,exec等危险字段。L4 记忆层向量检索前对 query 做敏感词脱敏如“如何黑进公司数据库” → “如何访问公司数据库”避免记忆库被恶意 probe。L5 规划层状态机定义禁止动作如“不得调用删除用户数据的工具”LLM 规划若包含直接拒绝执行。L6 输出层LLM 生成答案后用微调的小模型DistilBERT做 PII 识别和内容安全评分低分答案强制重写。L7 日志层所有操作日志经 Kafka 流入 SIEM 系统设置关联规则如“同一 IP 10 分钟内调用 5 次 delete_user 工具”触发告警。这套体系让我们在金融客户上线首月成功拦截 17 起越权操作尝试和 3 次数据泄露风险而误报率低于 0.2%。安全不是功能而是像空气一样的基础设施。3. 七个决策点每次编码前你必须回答的七个致命问题3.1 决策点一目标如何分解——选择“LLM 驱动”还是“规则驱动”的分水岭当你拿到一个用户需求第一反应不该是“用哪个大模型”而是“这个目标能否被穷举、可验证、有明确终点”。这是区分两种工程范式的分水岭。规则驱动适用场景目标结构固定、步骤明确、失败路径可枚举。例如“重置密码”流程1. 验证手机号 → 2. 发送验证码 → 3. 校验验证码 → 4. 更新密码。每一步都有确定性输入输出失败原因如手机号不存在、验证码错误可精准捕获。此时用状态机硬编码性能高、可测性强、成本低。我们为某银行做的密码重置 AgentQPS 达 1200P99 延迟 87ms而同类 LLM 方案 P99 延迟 1.2s 且错误率波动大。LLM 驱动适用场景目标模糊、需上下文理解、步骤不可预知。例如“帮我整理会议纪要”LLM 需理解发言人的角色、识别待办事项、提炼争议点。此时规则无法覆盖所有变体必须依赖 LLM 的泛化能力。但关键决策是LLM 只负责“理解”和“生成”不负责“执行”。会议纪要生成后由规则引擎调用邮件 API 发送而非让 LLM 自己写发送指令。实操心得我坚持一个铁律——任何需要调用外部系统数据库、API、文件系统的动作必须由确定性代码执行LLM 只能输出指令字符串。这避免了 LLM 因 token 限制或幻觉导致的执行错误。比如 LLM 说“更新用户表 id123 的 status 字段”但实际表名是user_profiles字段是account_status硬编码的 SQL 才能保证正确。3.2 决策点二状态存在哪——选择内存、Redis 还是数据库的黄金三角状态存储不是技术选型题而是一致性、性能、成本的三角博弈。我们用一张表说明决策逻辑场景数据特征推荐存储理由实测指标单次会话临时变量如当前步骤ID生命周期5分钟读写频繁内存零延迟无网络开销P99 0.1ms跨步骤共享状态如用户预算生命周期24小时需高并发读Redis毫秒级响应支持原子操作P99 2msQPS 5000用户长期偏好如默认收货地址生命周期1年需强一致性PostgreSQLACID 保障支持复杂查询写入延迟 15ms支持事务回滚关键陷阱是“过度设计”。曾有团队为所有状态上 PostgreSQL结果单次请求增加 3 次 DB 连接P99 延迟飙升至 400ms。后来我们砍掉 70% 的非必要持久化只保留真正需要审计和恢复的状态整体性能提升 3 倍。另一个教训Redis 不是万能的。当某电商客户要求“实时同步购物车状态到所有设备”我们发现 Redis 的 pub/sub 在网络抖动时会丢消息最终改用 Kafka 作为状态变更的可靠广播通道虽然架构变重但数据一致性从 99.2% 提升到 100%。3.3 决策点三工具如何集成——选择“直连”、“网关”还是“沙箱”的生死线工具集成方式直接决定系统的可维护性和安全性。三种模式的本质区别直连模式Agent 代码里直接写requests.post(weather_api_url, jsonpayload)。优点是简单缺点是1. 工具变更URL/参数需改代码发版2. 无统一熔断/限流3. 错误日志分散难聚合分析。我们只在 PoC 阶段用上线必淘汰。网关模式所有工具走统一网关如我们自研的 Rust 网关。优点是集中管控但风险是网关成为单点故障。我们的解法是网关无状态部署为 Kubernetes StatefulSet每个实例独立连接后端工具故障时 K8s 自动漂移用户无感。沙箱模式工具运行在隔离容器如 Firecracker MicroVM中Agent 通过 IPC 调用。这是最高安全等级适用于执行用户上传的 Python 脚本等高危操作。但性能损耗大启动容器 200ms我们只在金融风控场景启用。关键决策只要工具提供标准 HTTP 接口一律走网关。网关配置文件示例tools: - name: weather_query endpoint: https://api.example.com/weather timeout: 3000 # ms retry: 2 circuit_breaker: failure_threshold: 5 reset_timeout: 60000 # ms这个配置运维可随时调整无需工程师介入。3.4 决策点四记忆如何检索——选择“向量”、“关键词”还是“图谱”的精度权衡记忆检索不是技术先进性竞赛而是召回精度 vs 响应速度 vs 维护成本的权衡。我们用三个真实案例说明客服场景高精度用户问“上个月的发票怎么下载”需精准定位到“电子发票下载指南”文档的第 2 页。此时用向量检索Weaviate text-embedding-3-large配合关键词过滤doc_type: guide AND version: 2024召回准确率 92%。销售助手高速度销售实时查询“客户 A 的历史订单”需毫秒级返回。此时用 PostgreSQL 全文检索to_tsvector配合 B-tree 索引P99 延迟 8ms比向量库快 15 倍。研发知识库强关系工程师问“如何修复 Jenkins Pipeline 的权限错误”需关联“Jenkins 文档”、“K8s RBAC 配置”、“公司内部权限系统”三类知识。此时用 Neo4j 图数据库建立:HAS_ERROR、:REQUIRES_PERMISSION等关系召回相关性提升 40%。实操心得别迷信单一技术。我们构建了“记忆路由层”根据 query 的语义类型用小模型分类自动选择检索引擎。用户无感知系统却获得最佳平衡。3.5 决策点五规划如何执行——选择“状态机”、“LLM JSON”还是“DSL”的可靠性门槛规划执行的核心矛盾是LLM 的创造性 vs 工程的确定性。三种方案的可靠性光谱LLM JSON 模式LLM 输出{steps: [{tool: weather, params: {...}}, ...]}。最灵活但可靠性最低。我们测试过 1000 次调用JSON 格式错误率 12%工具名拼写错误率 8%参数缺失率 15%。DSL 模式定义领域特定语言如WEATHER(beijing, 2024-06-01) → FLIGHT(PEK, SHA, 2024-06-02)。LLM 只需生成 DSL 字符串由解释器执行。错误率降至 3%但开发 DSL 解释器成本高。状态机模式预定义流程骨架LLM 只填充参数。错误率 0.5%且可 100% 单元测试。这是我们生产环境的绝对首选。关键洞察90% 的业务流程其步骤序列是有限且可枚举的。与其花精力训练 LLM 学会写完美 JSON不如用 200 行代码写个健壮的状态机。我们为某物流客户做的“运单跟踪”Agent状态机仅 7 个节点却覆盖了 99.6% 的用户请求剩余 0.4% 的边缘 case由 LLM 的自由模式兜底——但这是有代价的兜底请求单独计费且超时后自动转人工。3.6 决策点六反思如何触发——选择“事前校验”、“事中监控”还是“事后审计”的时效性抉择反思的价值在于及时止损而非事后诸葛亮。三种触发时机的工程意义事前校验在 LLM 输出任何内容前校验输入是否合规如是否含恶意指令。这是成本最低、效果最好的防线。我们用正则规则引擎在 5ms 内完成拦截 99% 的越权尝试。事中监控在工具调用过程中实时捕获异常如超时、HTTP 500。这是保障流程不中断的关键。我们的工具网关内置 watchdog平均检测延迟 12ms。事后审计在流程结束后分析日志找根因。这无法防止问题发生但能优化系统。我们每天凌晨用 Spark 分析昨日所有失败请求自动生成“TOP3 失败原因”报告驱动迭代。我的决策原则把 80% 的精力放在事前和事中20% 放在事后。因为事后审计再深入也无法挽回一个已发生的资损。曾有个支付场景LLM 错误生成了重复扣款指令事后审计发现了但钱已经划走。后来我们强制在“扣款”工具调用前加入事前校验查询数据库确认该订单未支付才允许执行——从此零重复扣款。3.7 决策点七安全如何兜底——选择“输入过滤”、“输出净化”还是“执行隔离”的纵深防御安全不是加一道防火墙而是构建攻击者必须逐层突破的堡垒。我们的七层防御每一层解决不同维度的问题输入层防注入用 Drools 引擎规则库包含 200 条恶意模式如.*\$\{.*\}.*匹配 SpEL 表达式注入。工具层防越权网关强制校验每个工具的allowed_roles字段用户 token 权限不足则拒绝调用。执行层防逃逸沙箱模式下容器无网络、无磁盘写入权限只能通过预定义 IPC 接口通信。最关键的决策是永远假设 LLM 会输出恶意内容。因此我们禁用所有 LLM 的“代码执行”能力所有工具调用必须经网关二次校验。曾有客户要求“让 Agent 自动修复服务器故障”我们坚持只开放systemctl restart nginx这类白名单命令而非允许 LLM 自由写 shell 脚本——后者在一次红队测试中被诱导生成了rm -rf /。4. 工程实践从零搭建一个可上线的 Agent 的完整流水线4.1 环境准备为什么我们放弃 Python 主栈转向 Rust Python 混合架构最初我们用纯 PythonFastAPI LangChain搭建 Agent开发快但上线后问题频发内存泄漏LangChain 的某些链式调用会累积大量中间对象GC 无法及时回收3 天后内存占用达 8GBGIL 瓶颈高并发时CPU 利用率卡在 100%但 QPS 上不去因为 I/O 密集型任务被 GIL 阻塞依赖冲突不同工具包要求的openai版本不兼容pip install时常失败。痛定思痛我们重构为Rust 主干 Python 插件架构Rust 层实现核心七要素状态管理、工具网关、规划执行器利用其内存安全和零成本抽象P99 延迟稳定在 50ms 内内存占用恒定在 200MBPython 层仅封装 LLM 调用openai.ChatCompletion.create和向量检索weaviate.Client作为 Rust 的 FFI 插件加载。这样既享受 Rust 的性能又保留 Python 的生态便利。部署时用 Docker 构建多阶段镜像# 第一阶段Rust 编译 FROM rust:1.78-slim AS builder WORKDIR /app COPY Cargo.toml Cargo.lock ./ RUN cargo build --release --target x86_64-unknown-linux-musl # 第二阶段轻量运行 FROM gcr.io/distroless/cc-debian12 COPY --frombuilder /app/target/x86_64-unknown-linux-musl/release/agent-core /agent-core CMD [/agent-core]镜像大小仅 12MB无 Shell、无包管理器攻击面极小。实测在 4c8g 服务器上单实例支撑 3000 QPSCPU 利用率 65%远超 Python 方案。4.2 核心模块编码以“天气查询”为例手把手写出可测试的生产代码我们以最简单的“查询天气”功能演示如何写出可测试、可监控、可维护的代码。重点不在功能本身而在工程结构第一步定义工具契约OpenAPI# tools/weather.yaml openapi: 3.0.0 info: title: Weather API version: 1.0.0 paths: /query: post: summary: 查询城市天气 requestBody: required: true content: application/json: schema: type: object properties: city: type: string description: 城市拼音如 beijing example: beijing date: type: string format: date description: 查询日期格式 YYYY-MM-DD example: 2024-06-01 responses: 200: description: 成功 content: application/json: schema: type: object properties: aqi: type: integer description: 空气质量指数 level: type: string enum: [优, 良, 轻度污染, 中度污染, 重度污染, 严重污染] 400: description: 参数错误 500: description: 服务内部错误第二步Rust 工具网关实现关键片段// src/tool_gateway.rs use tokio::time::{Duration, timeout}; use reqwest::Client; pub struct WeatherTool { client: Client, timeout_ms: u64, } impl WeatherTool { pub fn new(timeout_ms: u64) - Self { Self { client: Client::new(), timeout_ms, } } // 执行调用带熔断和超时 pub async fn execute(self, city: str, date: str) - ResultWeatherResponse, ToolError { let url format!(https://api.weather.com/query?city{}date{}, city, date); // 熔断器检查简化版 if self.is_circuit_open() { return Err(ToolError::CircuitOpen); } // 超时控制 let result timeout(Duration::from_millis(self.timeout_ms), async { let resp self.client.get(url).send().await?; if resp.status().is_success() { let data resp.json::WeatherResponse().await?; Ok(data) } else { Err(ToolError::HttpError(resp.status().as_u16())) } }).await.map_err(|_| ToolError::Timeout)?; // 成功则重置熔断器 if result.is_ok() { self.reset_circuit(); } result } } #[derive(Deserialize)] pub struct WeatherResponse { pub aqi: i32, pub level: String, }第三步Python LLM 插件FFI 调用# llm_plugin.py import ctypes from typing import Dict, Any # 加载 Rust 编译的动态库 lib ctypes.CDLL(./target/release/libagent_core.so) lib.execute_weather.argtypes [ctypes.c_char_p, ctypes.c_char_p] lib.execute_weather.restype ctypes.c_char_p def query_weather(city: str, date: str) - Dict[str, Any]: # 调用 Rust 函数 result_ptr lib.execute_weather( city.encode(utf-8), date.encode(utf-8) ) # 解析 JSON 结果 import json return json.loads(ctypes.cast(result_ptr, ctypes.c_char_p).value.decode(utf-8))第四步编写单元测试Rust// tests/tool_gateway_test.rs #[cfg(test)] mod tests { use super::*; #[tokio::test] async fn test_weather_tool_success() { let tool WeatherTool::new(5000); // 使用 mock server 测试 let mock_server mockito::Server::new(); let mock mockito::mock(GET, /query) .match_query(mockito::Matcher::All) .with_status(200) .with_header

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询