AI智能体开发:从认知骨架到工程化落地的全流程解析

1. 这不是写代码,而是“造一个会思考的同事”——AI智能体开发到底在做什么?

很多人看到“AI智能体”四个字,第一反应是科幻电影里那个能自主决策、开口说话、甚至带点小脾气的机器人。其实离我们最近的智能体,可能就是你手机里那个能记住你常点哪家咖啡、主动提醒“今天降温该加件外套”的语音助手;或是你公司内部那个不用翻文档、直接回答“上季度华东区退货率超标的三个SKU是什么?原因分析报告在哪?”的业务助理。它不靠预设脚本硬扛所有问题,而是像一个刚入职三个月、但已经摸清公司流程、熟悉数据位置、知道该问谁要什么材料的新人——它有目标、会拆解、懂调用、能反思、还会迭代。

“AI智能体的开发流程”,说白了,就是把这种“类人协作能力”从模糊设想变成可运行、可维护、可进化的数字系统的过程。它和传统软件开发最根本的区别在于:你不是在写功能逻辑,而是在设计一套“认知操作系统”。这个系统要能理解模糊指令(比如“帮我梳理客户投诉里的高频情绪词”),能判断当前该调用哪个工具(是查CRM数据库?还是调用NLP情感分析API?还是生成一份可视化图表?),能在执行失败时换条路走(比如数据库连不上,就先用本地缓存数据做初步统计),还能把这次经验记下来,下次类似任务做得更快更准。

我带过好几个团队落地过这类项目,从电商客服辅助到制造业设备故障预判,发现最大的误区,就是把它当成“大模型+几个API调用”的拼凑活。结果做出来的东西,要么一问三不知,要么答非所问,要么卡在某个环节死循环。真正跑得稳的智能体,背后是一整套严谨的工程化闭环:从目标定义开始,就拒绝“让它聪明一点”这种虚话,必须明确“它要在什么场景下,对谁,解决哪类具体问题,效果如何量化”。比如不是“提升客服效率”,而是“将首次响应时间压缩至15秒内,且90%以上的问题无需人工转接”。这个目标,直接决定了你要给它配什么样的记忆模块、设定多细的工具调用权限、设计多深的自我反思层级。

这个流程之所以现在被反复讨论,并不是因为技术突然突破了,而是企业真实痛点到了临界点:大量重复性、跨系统、需上下文理解的脑力劳动,正卡在“人太忙没空教AI”和“AI太笨学不会规则”之间。而智能体开发,本质上是在搭建一座桥——一边是人的业务经验与判断直觉,另一边是机器的执行速度与数据处理广度。接下来我会带你一层层拆开这座桥的每一块砖:它怎么设计、怎么搭、怎么测、怎么防塌,全是我在产线踩坑后总结出的实操细节。

2. 智能体不是“堆模型”,而是“搭认知骨架”——整体设计与思路拆解

很多人一上来就想选最强的大模型,仿佛模型参数量越大,智能体就越“聪明”。这就像盖楼前先去挑最贵的钢筋,却忘了地基打在哪、承重墙怎么布局。真正的起点,永远是任务域建模——用一张清晰的图,画出这个智能体要服务的具体业务场景里,所有关键角色、数据流、决策点和约束条件。

2.1 为什么必须先画“任务域地图”,而不是急着写提示词?

我见过太多团队,在没搞清业务脉络前,就花两周时间精调GPT-4的system prompt,结果上线后发现:用户问“上个月流失客户的复购可能性”,模型能生成一篇漂亮的分析报告,但完全没调用真实的客户行为数据库,所有结论都是基于通用知识的合理想象。问题出在哪?不是模型不行,是任务域没定义清楚——“复购可能性”这个指标,在你们公司是由哪个系统计算?依据哪些字段?更新频率是多少?有没有人工审核环节?这些信息,必须在设计阶段就固化进智能体的“认知边界”里。

所以我的标准动作是:拉上业务方、数据工程师、一线使用者,一起画一张三层任务域地图:

  • 表层(用户可见层):列出所有典型用户指令,按高频、中频、低频分类。比如客服场景里,“查订单状态”是高频,“申请特殊退款”是中频,“解释某项政策的历史变更”是低频。高频指令决定响应速度SLA,中频指令决定工具链复杂度,低频指令则考验知识库覆盖深度。

  • 中层(系统交互层):标注每条指令背后需要调用的内部系统(CRM、ERP、BI平台)、外部API(物流查询、支付网关)、以及需要读取的结构化/非结构化数据源(工单文本、通话录音转录稿、产品说明书PDF)。特别注意标出各系统的认证方式(OAuth2.0?API Key?SAML单点登录?)和调用频次限制(比如物流API每分钟最多10次请求)。

  • 底层(约束与规则层):这是最容易被忽略、却最致命的一层。包括:数据权限(客服只能看自己负责的客户,不能跨区域查询)、合规红线(金融场景中禁止生成投资建议)、业务逻辑(退货必须先确认库存,再触发退款)、以及兜底策略(当所有工具都不可用时,返回哪句标准话术并转人工)。

这张图一旦定稿,后续所有技术选型都有了锚点。比如中层标出要频繁调用ERP的生产计划模块,那工具调用框架就必须支持长连接和会话保持;底层标出强合规要求,那整个推理链就必须设计成可审计、可回溯的步骤日志,不能只输出最终答案。

2.2 “智能体架构”不是玄学,而是四块确定性积木

市面上讲智能体架构的文章,动辄“感知-决策-执行-反思”四层,听着高大上,但落地时根本不知道每层该放啥。我把这套逻辑彻底具象化,拆成四个必须独立实现、又紧密咬合的模块,每个模块都有明确输入输出和验收标准:

  1. 目标解析器(Goal Parser)

    • 输入:用户原始指令(自然语言)
    • 输出:结构化任务描述(JSON格式),包含:核心动词(查询/生成/审批/预测)、主语(订单/客户/设备)、关键约束(时间范围/地域/状态)、预期输出格式(表格/文字摘要/图表链接)
    • 关键设计点:它不负责“理解”,只负责“提取”。比如用户说“帮我看看张三最近三次下单都买了啥,列个表”,它必须精准识别出:动词=“查看”,主语=“张三的订单”,次数=“3”,输出=“表格”。所有模糊表述(如“最近”、“都”)必须在此模块转换为确定值(如“最近=过去30天”,“都=全部商品明细”)。我通常用轻量级微调模型(如Phi-3-3.8B)做这件事,因为它快、可控、错误模式稳定,比用大模型做全链路解析更可靠。
  2. 工具调度器(Tool Orchestrator)

    • 输入:目标解析器输出的结构化任务
    • 输出:按顺序执行的工具调用指令序列(含参数、超时设置、重试策略)
    • 关键设计点:它像一个冷静的项目经理,不关心工具内部怎么工作,只关心“谁在什么时候该干什么”。比如任务要求“查张三订单+分析商品关联性”,它必须判断:先调用CRM查订单(耗时<2s),再把订单ID传给推荐引擎API做关联分析(耗时<5s),如果推荐API超时,则降级为用本地规则库匹配(耗时<100ms)。这个模块的代码必须可配置、可热更新——业务规则变了,改配置文件就行,不用动代码。
  3. 记忆协调器(Memory Coordinator)

    • 输入:当前任务上下文 + 历史交互片段(用户偏好、常用筛选条件、已确认的事实)
    • 输出:注入当前推理过程的上下文增强包(Context Augmentation Package)
    • 关键设计点:它不是简单存聊天记录,而是分层管理记忆。短期记忆(本次对话内的实体指代,如“它”指代上句提到的设备)用LLM的上下文窗口;中期记忆(用户习惯,如“王经理总要导出Excel”)存在Redis里,带TTL自动过期;长期记忆(公司制度、产品参数)存在向量数据库,但必须带来源标记和最后验证时间。最关键的是,每次调用前,它必须做一次“记忆可信度校验”——比如用户说“按上月标准”,它得先查数据库确认“上月标准”当前是否有效,而不是盲目信任历史记录。
  4. 反思评估器(Reflection Evaluator)

    • 输入:工具执行结果 + 用户反馈(显式评价如“不对”,或隐式信号如“再详细点”、“换个说法”)
    • 输出:本次任务的执行质量评分(0-100) + 可操作的优化建议(如“CRM接口平均延迟升至3.2s,建议增加缓存”、“用户70%追问集中在价格解释,需补充定价规则知识库”)
    • 关键设计点:它不追求“完美反思”,而追求“可落地改进”。我坚持用规则引擎(Drools)而非大模型来做这事,因为规则明确:当用户连续两次说“没听懂”,就触发术语解释流程;当工具调用失败率>15%,就自动告警并降级;当某类问题人工介入率突增,就标记相关知识库条目待审核。所有建议必须指向具体责任人和行动项,比如“请数据组在24小时内验证CRM订单状态字段的ETL延迟”。

这四个模块,构成了智能体的“认知骨架”。它们之间通过定义清晰的API契约通信,任何模块都可以独立替换、升级、压测。这才是工程化的核心——把不确定性(大模型的幻觉、网络抖动、数据漂移)关进确定性的笼子里。

3. 从蓝图到可运行:核心细节解析与实操要点

设计图再漂亮,不落地就是废纸。我把智能体开发中最容易栽跟头的五个核心细节,掰开揉碎讲透。这些不是理论,而是我在三个不同行业项目里,用真金白银试错换来的血泪经验。

3.1 目标解析器:别让“自然语言理解”毁掉整个链条

很多团队把目标解析器做成一个黑盒大模型调用,结果发现:模型对“帮我查一下昨天的销售”能准确提取时间,但对“帮我查一下上个周五的销售”就经常错判成“上周五”(实际是7天前,而非5天前)。问题根源在于,自然语言的时间表达,本质是业务规则,不是语言学问题。

我的解决方案是“双轨制解析”:

  • 规则轨道(Rule Track):用正则+业务词典硬编码所有确定性表达。比如:

    # 预定义时间词典 TIME_KEYWORDS = { "今天": lambda: datetime.now().date(), "昨天": lambda: datetime.now().date() - timedelta(days=1), "本周": lambda: (datetime.now().date() - timedelta(days=datetime.now().weekday())), "上个周五": lambda: get_last_friday(), # 自定义函数,精确计算 }

    所有出现在业务文档、客服话术、内部邮件里的固定时间表达,必须穷举入库。这部分覆盖了85%以上的高频指令。

  • 模型轨道(Model Track):只处理规则无法覆盖的模糊表达,如“旺季开始后”、“促销活动期间”。此时才调用微调后的Phi-3模型,但输入必须经过严格清洗:去掉语气词、标准化缩写(“Q3”→“第三季度”)、强制补全上下文(“促销活动期间”→“2024年Q3大促活动期间”)。模型输出不是最终结果,而是多个候选解析(带置信度),由规则轨道做最终仲裁。

提示:在测试阶段,必须用“对抗样本”暴击这个模块。比如故意输入“上上个周一的销售”,看它是否报错而不是瞎猜;输入“上个月的今天”,看它是否意识到2月没有30号。我要求每个时间解析规则,必须附带10个以上真实业务场景下的正反例测试用例,通不过就重写。

3.2 工具调度器:API不是万能胶,而是需要精心设计的“关节”

调度器常犯的错误,是把所有API当平等公民对待。但现实是:查库存的API毫秒级响应,调用外部征信API可能要等15秒,而生成一份PDF报告的后台任务,根本就是异步的。如果调度器不懂区分,整个智能体就会卡死。

我的实践是给每个工具打上三维度标签:

工具ID响应类型平均延迟失败降级方案
crm_order_query同步120ms返回缓存数据(TTL=5min)
external_credit_check同步8.2s跳过此步,标记“信用信息待补”
report_generator异步N/A(任务ID)发送邮件通知,附带下载链接

调度器根据这些标签,动态生成执行策略:

  • 对同步短延迟工具(<500ms),直接串行调用;
  • 对同步长延迟工具(>2s),启动并行调用,但设置严格超时(如3s),超时即切降级方案;
  • 对异步工具,立即返回“任务已提交,预计X分钟后邮件通知”,并在后台轮询状态,状态变更时主动推送。

最关键的是,所有工具调用必须封装成“带契约的函数”。比如crm_order_query的契约定义:

def crm_order_query( customer_id: str, date_range: tuple[date, date], # 必须是确定日期,不接受"最近" max_results: int = 100 # 防止OOM ) -> List[OrderItem]: """ 【前置校验】customer_id必须匹配CRM正则 ^C\d{8}$ 【后置校验】返回订单数不能超过max_results,否则抛异常 【超时】硬性300ms,超时抛TimeoutError """

这个契约,既是开发规范,也是测试用例的源头。每次工具升级,只要契约不变,调度器代码零修改。

3.3 记忆协调器:别把“记住”当成“背诵”,要分层分级管理

新手常犯的错误,是把所有对话历史塞进LLM上下文,美其名曰“增强记忆”。结果模型越来越慢,还总把三天前用户随口说的“我喜欢吃辣”当成当前订单的口味偏好。

我的分层记忆架构如下:

  • 瞬时记忆(Session Memory):仅存于当前HTTP请求生命周期,存储本次对话的实体指代链(如“它”→“刚才提到的服务器”)。用Python字典实现,无持久化,请求结束即销毁。

  • 会话记忆(Conversation Memory):存于Redis,Key为conv:{session_id},Value为有序列表,每条记录包含:时间戳、用户消息、系统回复、关键实体提取结果。TTL设为24小时,自动过期。重点是,每次写入前,必须做实体消歧:检测新消息中的“它”是否与历史中的某个实体匹配,匹配则更新该实体的最新状态,不匹配则新建。

  • 用户画像记忆(User Profile Memory):存于PostgreSQL,表结构包含user_id,preference_key,preference_value,last_updated,source(来源:用户显式设置/系统推断/管理员配置)。关键设计是source字段——当用户说“以后都用简体中文”,source设为user_explicit,权重最高;当系统根据用户常访问页面推断“偏好技术文档”,source设为system_inferred,权重较低,且带confidence_score。记忆协调器读取时,按source权重和last_updated时间综合排序,确保最可靠、最新的信息优先注入。

  • 知识库记忆(Knowledge Base Memory):存于向量数据库(如Qdrant),但绝不直接存原文。每条知识必须经过“三重加工”:① 提取核心事实(如“XX型号服务器保修期3年”);② 标注适用场景(scene: hardware_support);③ 标注权威来源和时效(source: official_manual_v2.3, valid_from: 2024-01-01)。检索时,不仅匹配语义,更强制过滤scene和valid_from,避免把过期政策当现行规则。

注意:所有记忆写入操作,必须是原子的。我用Redis的MULTI/EXEC事务包裹会话记忆更新,用PostgreSQL的INSERT ... ON CONFLICT DO UPDATE处理用户画像,确保并发写入不丢数据。曾经有个项目因忘记加事务,导致用户偏好被覆盖,花了两天才从日志里还原。

3.4 反思评估器:让智能体“学会吃亏”,而不是“假装聪明”

很多团队的反思模块,就是让大模型读一遍对话,然后写个“本次服务很好”的总结。这毫无价值。真正的反思,必须驱动可测量的改进。

我的评估器采用“三层漏斗”机制:

  1. 基础层(Automated Checks):纯规则,毫秒级完成。检查项包括:

    • 工具调用是否全部成功(失败率>0%即告警)
    • 响应时间是否超SLA(如客服场景>15s)
    • 输出是否包含禁止词汇(如“绝对”、“肯定”、“100%”等绝对化表述)
    • 是否触发了兜底话术(如“我暂时无法回答,请联系人工”)
  2. 体验层(User Signal Analysis):分析用户隐式反馈。比如:

    • 用户发送“?”或“。。。”,视为困惑信号;
    • 用户重复提问同一问题(相似度>85%),视为未理解;
    • 用户在回复后立即发起新会话(间隔<30s),视为不满意。
  3. 价值层(Business Impact Review):对接业务系统,验证结果有效性。例如:

    • 客服场景:调用CRM API,确认智能体给出的解决方案,是否真的关闭了对应工单;
    • 销售场景:调用BI系统,确认智能体推荐的客户,30天内是否产生了新订单。

只有同时通过三层检查的任务,才被标记为“成功”。任一层失败,评估器就生成一条结构化改进项,写入内部Jira系统,自动分配给对应负责人。比如:“CRM订单查询工具在14:00-15:00时段失败率升至22%,建议检查数据库连接池配置”,这条记录会直接创建为运维组的紧急任务。

3.5 安全与合规:不是加个防火墙,而是把红线刻进每一行代码

在金融、医疗、政务类项目中,安全不是附加功能,而是设计前提。我见过最危险的做法,是把敏感数据过滤放在LLM输出后——相当于让模型先“看过”所有客户身份证号,再让另一个程序把它们抹掉。幻觉和缓存,会让这种做法形同虚设。

我的“安全左移”实践:

  • 输入净化(Input Sanitization):在目标解析器之前,就部署正则过滤器,拦截所有疑似PII(个人身份信息)的输入。比如用户输入“查张三138****1234的订单”,过滤器会立即报错:“检测到手机号,为保护隐私,请使用客户ID查询”。这个过滤器必须独立部署,不依赖任何模型。

  • 上下文隔离(Context Isolation):每个工具调用,都在独立的沙箱环境中执行。CRM工具的沙箱,只允许访问orders和customers两张表,且customers表自动脱敏(id_card字段返回***,phone字段返回138****1234)。沙箱环境由数据库代理(如ProxySQL)实现,规则写死在代理层,应用代码无权绕过。

  • 输出审计(Output Auditing):所有最终回复,必须经过审计模块签名。签名内容包括:原始用户指令哈希、调用的工具链(含版本号)、关键数据字段的哈希(如订单号)、生成时间戳。这个签名存于区块链存证服务(如蚂蚁链),不可篡改。一旦发生纠纷,可凭签名秒级追溯完整执行路径。

  • 人工熔断(Human-in-the-loop):对高风险操作(如“冻结账户”、“修改合同金额”),调度器必须强制插入人工审批节点。不是弹窗让用户点“确定”,而是将请求推送到指定审批人企业微信,审批人必须用生物识别(指纹/人脸)二次确认,审批记录实时同步至审计链。

这些不是锦上添花,而是项目上线的准入门槛。我坚持一个原则:任何安全措施,如果不能在开发环境用单元测试覆盖,就不算真正落地。比如PII过滤器,必须有100%覆盖率的测试用例,涵盖所有国内身份证、手机号、银行卡号的正则变体。

4. 实操全过程:从零搭建一个电商客服智能体

现在,我们把前面所有理念,浓缩成一个可立即上手的实战案例:为一家中型电商公司,搭建一个处理“订单状态查询”的智能体。全程基于开源技术栈,不依赖任何商业API,所有代码均可在本地复现。

4.1 环境准备与依赖安装

我们选择极简但生产可用的技术组合:Python 3.11 + FastAPI(Web框架)+ LangChain(编排)+ Qdrant(向量库)+ PostgreSQL(结构化数据)+ Redis(缓存)。所有组件均用Docker Compose一键拉起,避免环境差异。

# 创建项目目录 mkdir ecommerce-agent && cd ecommerce-agent # 初始化docker-compose.yml cat > docker-compose.yml << 'EOF' version: '3.8' services: # PostgreSQL - 存储订单、用户、产品数据 db: image: postgres:15 environment: POSTGRES_DB: ecommerce POSTGRES_USER: agent POSTGRES_PASSWORD: secret volumes: - ./data/db:/var/lib/postgresql/data ports: - "5432:5432" # Redis - 存储会话记忆和缓存 redis: image: redis:7-alpine command: redis-server --save 60 1 --loglevel warning volumes: - ./data/redis:/data ports: - "6379:6379" # Qdrant - 存储产品知识库(向量化) qdrant: image: qdrant/qdrant volumes: - ./data/qdrant:/qdrant/storage ports: - "6333:6333" # 后端API服务 api: build: . ports: - "8000:8000" depends_on: - db - redis - qdrant environment: DB_URL: postgresql://agent:secret@db:5432/ecommerce REDIS_URL: redis://redis:6379/0 QDRANT_URL: http://qdrant:6333 EOF # 创建Dockerfile cat > Dockerfile << 'EOF' FROM python:3.11-slim WORKDIR /app COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt COPY . . CMD ["uvicorn", "main:app", "--host", "0.0.0.0:8000", "--port", "8000"] EOF # 创建依赖文件 cat > requirements.txt << 'EOF' fastapi==0.110.0 uvicorn==0.29.0 psycopg2-binary==2.9.9 redis==4.6.0 qdrant-client==1.8.0 langchain==0.1.15 langchain-community==0.0.25 sentence-transformers==2.2.2 pydantic==2.7.1 SQLAlchemy==2.0.29 EOF # 初始化数据库结构 cat > init_db.sql << 'EOF' CREATE TABLE IF NOT EXISTS orders ( id SERIAL PRIMARY KEY, order_id VARCHAR(32) UNIQUE NOT NULL, customer_id VARCHAR(32) NOT NULL, status VARCHAR(20) NOT NULL CHECK (status IN ('pending', 'shipped', 'delivered', 'cancelled')), created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), shipped_at TIMESTAMP WITH TIME ZONE, delivered_at TIMESTAMP WITH TIME ZONE ); CREATE TABLE IF NOT EXISTS customers ( id SERIAL PRIMARY KEY, customer_id VARCHAR(32) UNIQUE NOT NULL, name VARCHAR(100), phone VARCHAR(20) ); -- 插入测试数据 INSERT INTO customers (customer_id, name, phone) VALUES ('C001', '张三', '138****1234'), ('C002', '李四', '159****5678'); INSERT INTO orders (order_id, customer_id, status, created_at, shipped_at) VALUES ('ORD-2024-001', 'C001', 'shipped', '2024-05-01 10:00:00+00', '2024-05-02 14:30:00+00'), ('ORD-2024-002', 'C002', 'delivered', '2024-05-03 09:15:00+00', '2024-05-04 11:20:00+00'), ('ORD-2024-003', 'C001', 'pending', '2024-05-05 16:45:00+00', NULL); EOF # 启动服务 docker-compose up -d --build # 等待服务就绪后,初始化数据库 docker-compose exec db psql -U agent -d ecommerce -f /app/init_db.sql

这段脚本会在本地启动一个完整的电商数据环境。注意,phone字段在数据库里是明文(便于演示),但在实际生产中,必须在应用层加密存储,且所有SQL查询都通过ORM的@hybrid_property自动脱敏。

4.2 构建目标解析器:让智能体听懂“查订单”

我们不调用大模型,而是用LangChain的StructuredOutputParser+ 自定义正则,构建一个轻量、确定、可测试的目标解析器。

# parser.py from langchain.output_parsers import StructuredOutputParser, ResponseSchema from langchain.prompts import PromptTemplate import re from typing import Dict, Optional # 定义输出结构 response_schemas = [ ResponseSchema(name="action", description="动作类型,如'query_order'"), ResponseSchema(name="order_id", description="订单ID,如'ORD-2024-001'"), ResponseSchema(name="customer_id", description="客户ID,如'C001'"), ResponseSchema(name="time_range", description="时间范围,如'2024-05-01 to 2024-05-05'"), ] output_parser = StructuredOutputParser.from_response_schemas(response_schemas) # 构建提示模板(注意:这里只是引导,核心逻辑在正则) prompt_template = """你是一个电商客服智能体的目标解析器。 请严格按JSON格式输出,只包含以下字段:action, order_id, customer_id, time_range。 不要添加任何额外说明或解释。 用户指令:{input} {format_instructions} """ prompt = PromptTemplate( template=prompt_template, input_variables=["input"], partial_variables={"format_instructions": output_parser.get_format_instructions()} ) # 核心正则解析器(主逻辑) class OrderQueryParser: def __init__(self): # 预编译正则,提高性能 self.order_id_pattern = re.compile(r'(ORD-\d{4}-\d{3})', re.IGNORECASE) self.customer_id_pattern = re.compile(r'(C\d{3})', re.IGNORECASE) self.time_keywords = { '今天': lambda: self._today(), '昨天': lambda: self._yesterday(), '最近': lambda: self._last_7_days(), } def parse(self, user_input: str) -> Dict: # 步骤1:提取订单ID order_id_match = self.order_id_pattern.search(user_input) order_id = order_id_match.group(1) if order_id_match else None # 步骤2:提取客户ID customer_id_match = self.customer_id_pattern.search(user_input) customer_id = customer_id_match.group(1) if customer_id_match else None # 步骤3:提取时间范围(简化版,实际项目需更复杂) time_range = None for kw, func in self.time_keywords.items(): if kw in user_input: time_range = func() break # 步骤4:确定动作 action = "query_order" if "取消" in user_input or "作废" in user_input: action = "cancel_order" elif "发货" in user_input or "寄出" in user_input: action = "ship_order" return { "action": action, "order_id": order_id, "customer_id": customer_id, "time_range": time_range } def _today(self): from datetime import datetime return datetime.now().strftime("%Y-%m-%d") def _yesterday(self): from datetime import datetime, timedelta return (datetime.now() - timedelta(days=1)).strftime("%Y-%m-%d") def _last_7_days(self): from datetime import datetime, timedelta start = datetime.now() - timedelta(days=7) end = datetime.now() return f"{start.strftime('%Y-%m-%d')} to {end.strftime('%Y-%m-%d')}" # 测试解析器 if __name__ == "__main__": parser = OrderQueryParser() test_cases = [ "查一下订单ORD-2024-001的状态", "C001最近下的单有哪些?", "昨天发货的订单", ] for case in test_cases: print(f"输入: {case}") print(f"输出: {parser.parse(case)}\n")

运行测试,你会看到:

输入: 查一下订单ORD-2024-001的状态 输出: {'action': 'query_order', 'order_id': 'ORD-2024-001', 'customer_id': None, 'time_range': None} 输入: C001最近下的单有哪些? 输出: {'action': 'query_order', 'order_id': None, 'customer_id': 'C001', 'time_range': '2024-05-01 to 2024-05-08'}

这个解析器的优势在于:100%可预测、100%可测试、100%免模型。你可以为每个业务场景编写50个真实用户语句作为测试用例,确保覆盖率。这才是工程化的起点。

4.3 开发工具调度器:让智能体“会干活”

调度器的核心是Tool抽象。我们为订单查询创建一个符合LangChain标准的工具:

# tools/order_tool.py from langchain.tools import BaseTool from pydantic import BaseModel, Field from typing import Optional, Type import psycopg2 from psycopg2.extras import RealDictCursor class OrderQueryInput(BaseModel): order_id: Optional[str] = Field(description="订单ID,如ORD-2024-001") customer_id: Optional[str] = Field(description="客户ID,如C001") limit: int = Field(default=10, description="最多返回多少条记录") class OrderQueryTool(BaseTool): name = "order_query" description = "查询订单状态。可按订单ID或客户ID查询。" args_schema: Type[BaseModel] = OrderQueryInput def _run( self, order_id: Optional[str] = None, customer_id: Optional[str] = None, limit: int = 10 ) -> str: # 1. 连接数据库(生产中应使用连接池) conn = psycopg2.connect( host="db", database="ecommerce", user="agent", password="secret" ) cursor = conn.cursor(cursor_factory=RealDictCursor) try: # 2. 构建安全SQL(防止SQL注入) if order_id: query = "SELECT * FROM orders WHERE order_id = %s LIMIT %s" params = (order_id, limit) elif customer_id: query = "SELECT * FROM orders WHERE customer_id = %s ORDER BY created_at DESC LIMIT %s" params = (customer_id, limit) else: return "错误:必须提供订单ID或客户ID。" cursor.execute(query, params) rows = cursor.fetchall() # 3. 格式化结果(脱敏手机号) result = [] for row in rows: # 从customers表获取客户姓名,脱敏手机号 cursor.execute("SELECT name, phone FROM customers WHERE customer_id = %s", (row['customer_id'],)) cust_row = cursor.fetchone() if cust_row: # 脱敏手机号:138****1234 masked_phone = cust_row['phone'][:3] + "****" + cust_row['phone'][-4:] result.append({ "order_id": row['order_id'], "customer_name": cust_row['name'], "customer_phone": masked_phone, "status": row['status'], "created_at": row['created_at'].strftime("%Y-%m-%d %H:%M") }) if not result: return "未找到符合条件的订单。" # 4. 生成自然语言回复 if len(result) == 1: item = result[0] return f"订单{item['order_id']}状态为{item['status']},客户{item['customer_name']},下单

相关新闻

从零手写C语言核心数据结构:动态数组、链表、哈希表与二叉搜索树

从零手写C语言核心数据结构:动态数组、链表、哈希表与二叉搜索树

1. 为什么还要从零手写数据结构&#xff1a;先回答“值不值”这两年我陆续把好几个项目的核心模块从脚本语言重写回 C&#xff0c;最大的感触不是性能数字好看&#xff0c;而是思路被迫变得特别清楚。C 语言没有现成的HashMap、没有链表库、没有自动扩容的数组&#xff0c;你手…

2026/10/21 6:28:35 阅读更多 →
App门户界面设计:从用户行为出发的工程化实践

App门户界面设计:从用户行为出发的工程化实践

1. 项目概述&#xff1a;这不是一个“点几下就完事”的界面配置&#xff0c;而是一次对移动应用底层交互逻辑的系统性梳理“作业一&#xff1a;app门户界面设置”——看到这个标题&#xff0c;很多刚接触移动开发或产品设计的新手会下意识觉得&#xff1a;“不就是改个首页样式…

2026/10/21 6:28:35 阅读更多 →
大模型从Token预测到状态预测的范式迁移

大模型从Token预测到状态预测的范式迁移

1. 这不是一次技术微调&#xff0c;而是一次范式迁移的预演“如果大模型不再预测下一个 Token&#xff0c;而是预测下一个状态”——这句话刚在某技术社区冒头&#xff0c;就迅速被转发上千次。它不像“多模态”“RAG”“MoE”那样指向某个可落地的工程模块&#xff0c;也不像“…

2026/10/21 6:28:35 阅读更多 →

最新新闻

Buck-Boost变换器仿真设计:从开环计算到闭环补偿

Buck-Boost变换器仿真设计:从开环计算到闭环补偿

最近在做某车载电源项目时&#xff0c;需要把一个波动范围很宽的电池电压&#xff08;9V到16V&#xff09;稳定成5V输出&#xff0c;给传感器电路供电。输入可能比输出高&#xff0c;也可能比输出低&#xff0c;普通的Buck或Boost拓扑都搞不定&#xff0c;只能上Buck-Boost。而…

2026/10/21 7:19:55 阅读更多 →
卫星图像降雨预测实战:从数据对齐到模型部署的完整技术路线

卫星图像降雨预测实战:从数据对齐到模型部署的完整技术路线

卫星图像预测降雨&#xff0c;听起来像是一个标准计算机视觉任务&#xff1a;数据是云图&#xff0c;标签是雨量&#xff0c;训练一个分割模型就完事。我第一次接触这类需求时也是这么想的&#xff0c;真到动手才发现&#xff0c;模型反而是整个链条里最不费心思的部分&#xf…

2026/10/21 7:19:55 阅读更多 →
AI Agent编排层故障排查:上下文窗口、工具调用与稳定性的工程实践

AI Agent编排层故障排查:上下文窗口、工具调用与稳定性的工程实践

很长一段时间里&#xff0c;我都在围绕 AI Agent 的编排层做工作&#xff0c;也就是圈子里常说的 Agent Harness Engineering。这个环节介于模型能力和业务场景之间&#xff0c;干的是工具注册、上下文管理、状态流转、调用编排这些不怎么光鲜、但是决定系统能不能真正跑起来的…

2026/10/21 7:19:55 阅读更多 →
基于PyTorch的时空预测模型复现:图卷积与时间卷积工程实践

基于PyTorch的时空预测模型复现:图卷积与时间卷积工程实践

简介&#xff1a;这是一份面向时空预测模型研究与PyTorch进阶学习者的PyTorch复现代码包。针对交通流量、气象等序列预测场景&#xff0c;资源将多个论文模型拆解为内聚的小Module再组装&#xff0c;便于读者对照公式与图示理解结构&#xff0c;并适配(batch, sequence, channe…

2026/10/21 7:19:55 阅读更多 →
AI威胁检测实战指南:从数据治理到模型落地的全链路解析

AI威胁检测实战指南:从数据治理到模型落地的全链路解析

今年一直在折腾一套东西&#xff1a;把AI和大数据技术揉进安全检测里&#xff0c;做智能威胁检测。说白了&#xff0c;就是让机器自己去流量、日志里找坏人&#xff0c;别总靠人肉盯。这个方向最近特别火&#xff0c;但真正落地过的人都知道&#xff0c;里面坑多水深&#xff0…

2026/10/21 7:19:55 阅读更多 →
寒区块石路基水热力耦合与冻胀变形的COMSOL模拟要诀

寒区块石路基水热力耦合与冻胀变形的COMSOL模拟要诀

一提到寒区路基&#xff0c;干这行的人第一反应通常都是那六个字——冻胀、融沉、翻浆。我前两年接了一个某寒区道路工程的数值评估任务&#xff0c;核心就是把一段块石路基的水热力耦合行为在COMSOL里算清楚&#xff0c;最后落到冻胀变形预测上。这类项目看着是纯仿真&#xf…

2026/10/21 7:18:55 阅读更多 →

日新闻

统一内存+量化:锐龙AI Max PRO 400如何本地跑320B大模型

统一内存+量化:锐龙AI Max PRO 400如何本地跑320B大模型

这段时间硬件圈和AI圈都在传一个事&#xff1a;AMD锐龙AI Max PRO 400系列把最高192GB统一内存搬进了PC形态的产品里&#xff0c;按宣传口径&#xff0c;本地跑320B参数的大家伙不再是纸面概念。我第一反应倒不是“内存真大”&#xff0c;而是这话背后的含金量——它把过去只能…

2026/10/21 0:00:11 阅读更多 →
AI助手深度使用体验:对话质量、长文本处理与指令遵循如何留住用户

AI助手深度使用体验:对话质量、长文本处理与指令遵循如何留住用户

1. 从“封号重开”这个行为说起&#xff1a;用户到底在追求什么“封号重开”这四个字&#xff0c;放在任何产品语境里都带着一股决绝的味道。一个账号从零开始积累使用记录、调教偏好、沉淀工作流&#xff0c;背后是大量的时间和精力成本。正常情况下&#xff0c;没有人愿意主动…

2026/10/21 0:00:11 阅读更多 →
ROS中YOLOv3工程落地:通信同步、坐标变换与性能调优

ROS中YOLOv3工程落地:通信同步、坐标变换与性能调优

1. 为什么在ROS里硬刚YOLOv3不是“炫技”&#xff0c;而是工程落地的必经之路我第一次在某高校机器人实验室看到那台搭载Jetson TX2的移动底盘原地打转、反复识别错垃圾桶时&#xff0c;就意识到&#xff1a;单纯跑通darknet_ros demo和真正让YOLOv3在ROS里“干活”&#xff0c…

2026/10/21 0:00:11 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型&#xff08;GMM&#xff09;的语音识别系统&#xff0c;很多人第一反应就是一堆数学公式&#xff0c;觉得门槛很高。但如果你真的在MATLAB里把它落地跑通&#xff0c;会发现核心其实就是三件事&#xff1a;把声音变成特征向量&#xff0c;用GMM给每个类别…

2026/10/20 10:02:13 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人&#xff0c;但落到具体操作上&#xff0c;无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程&#xff1a;对图像做反白、改调色板、彩色转灰度&#xff0c;最后把像素数据导出成txt文件。单看每一…

2026/10/20 20:43:59 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词&#xff0c;你会发现一个很有意思的现象&#xff1a;每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型&#xff0c;有人指的是运动控制系统&#xff0c;还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/21 4:27:17 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 10:02:08 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 9:50:17 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 9:50:45 阅读更多 →