动手做AI Agent:从可运行Demo到生产级落地的完整路径

发布时间:2026/10/8 19:55:43
动手做AI Agent:从可运行Demo到生产级落地的完整路径 简介本资源是黄佳所著《大模型应用开发 动手做AI Agent》PDF电子书面向AI开发者、算法工程师、产品经理及高校师生系统解决大模型时代Agent从概念理解到工程落地的核心问题。全书以7个递进式实战项目为脉络覆盖基于OpenAI Assistants API的PPT自动生成、LangChain ReAct框架的自动定价、LlamaIndex驱动的RAG知识整合、AutoGen与MetaGPT多Agent协同等关键技术场景深度解析Agent在办公自动化、智能调度与决策执行中的实现逻辑。资源为单文件PDF格式共1个文件大小25.35MB内容完整涵盖技术原理、工具选型对比、代码结构说明及前沿趋势展望便于离线研读与快速查阅。目前已有984人下载学习读者可直接获取从GPT-4调用、Function Calling设计到多Agent协作的全流程实践范式掌握构建自主性、工具化、可扩展AI Agent的关键能力。1. 为什么“动手做AI Agent”不是写个提示词就完事大模型应用开发的真实水位线你花三小时调通一个 LLM API喂进几条 prompt返回结果看着像那么回事——这不叫 AI Agent 开发。真正的「动手做 AI Agent」是让模型在没有人工干预的前提下能自主拆解目标、调用工具、处理异常、回溯失败、重试策略、收敛到可验证结果。它不是对话增强而是任务闭环不是模型调用封装而是认知流程编排。黄佳老师这本《大模型应用开发 动手做AI Agent》之所以被大量开发者反复翻烂正因为它踩在了当前落地最痛的断层上90% 的人卡在「能跑通 demo」和「能交付生产级 Agent」之间那道看不见的墙。这本书不讲 Transformer 推导不堆论文引用全篇用可执行代码带出 LangChain LlamaIndex Tool Calling Memory 管理四层骨架每章都配真实业务场景比如自动查天气订会议室同步日历连错误日志截图都带着 timestamp 和 stack trace。适合两类人一是刚从微调/部署转向应用层的工程师需要把「模型能力」翻译成「用户价值」二是业务侧技术负责人想快速判断团队是否真具备 Agent 工程化能力——而不是靠人工兜底的“伪智能”。2. 从零启动用 LangChain v0.1.18 搭建第一个可调试 Agent 骨架LangChain 是当前最主流的 Agent 编排框架但它的版本迭代极快v0.1.x 和 v0.2.x 的 API 断层极大。本书实操基于v0.1.182024 年 3 月稳定版这是目前企业项目中兼容性最好、文档最全、调试链路最透明的版本。我们不走pip install langchain一步到位的老路而是手动锁定依赖避免因langchain-community或langchain-core版本错配导致AgentExecutor初始化失败。2.1 创建隔离环境并安装精确版本链# 新建虚拟环境推荐 conda避免 pip 冲突 conda create -n agent-dev python3.10 conda activate agent-dev # 严格按本书配套 requirements.txt 安装注意顺序 pip install --no-deps langchain0.1.18 pip install --no-deps langchain-community0.0.34 pip install --no-deps langchain-core0.1.46 pip install --no-deps langchain-openai0.1.5 # 若用 OpenAI pip install tiktoken # 必装否则 TokenCountingHandler 报错 pip install pydantic1.10.17 # 关键v2.x 会导致 BaseTool 初始化失败提示pydantic1.10.17是本书所有 Tool 定义能正常注册的前提。LangChain v0.1.x 全量依赖 Pydantic v1而pip install langchain默认拉 v2这是新手第一坑。2.2 构建最小可运行 AgentReAct 模式 本地工具桩本书第一章的 demo 不用真实 API而是用BaseTool实现一个「模拟计算器」重点验证 Agent 的推理-行动-观察循环是否真正打通# calculator_tool.py from langchain.tools import BaseTool from pydantic import BaseModel, Field from typing import Optional, Type class CalculatorInput(BaseModel): a: float Field(..., description第一个数字) b: float Field(..., description第二个数字) operation: str Field(..., description运算符支持 - * /) class CalculatorTool(BaseTool): name calculator description 用于执行基础四则运算的工具。输入两个数字和运算符返回结果。 args_schema: Type[BaseModel] CalculatorInput def _run(self, a: float, b: float, operation: str) - str: try: if operation : return str(a b) elif operation -: return str(a - b) elif operation *: return str(a * b) elif operation /: if b 0: return 错误除数不能为零 return str(a / b) else: return 错误不支持的运算符 except Exception as e: return f计算异常{str(e)} def _arun(self, a: float, b: float, operation: str) - str: raise NotImplementedError(同步工具不支持异步调用)逻辑说明args_schema强制声明输入结构这是 Agent 能正确解析Thought:后Action Input:的关键_run()返回str类型LangChain v0.1.x 的AgentExecutor只接受字符串输出若返回float或dict会直接 crash_arun()抛NotImplementedError是显式告知框架“此工具不支持异步”避免后续误用asyncio.run()导致死锁。2.3 组装 Agent 并注入 LLM用 OpenAI GPT-3.5-turbo 做首次验证# main.py from langchain.agents import initialize_agent, AgentType from langchain_openai import ChatOpenAI from langchain.memory import ConversationBufferMemory from calculator_tool import CalculatorTool # 初始化 LLM务必设置 temperature0 保证确定性 llm ChatOpenAI( model_namegpt-3.5-turbo, temperature0, openai_api_keysk-xxx, # 替换为你自己的 key max_tokens512 ) # 注册工具 tools [CalculatorTool()] # 设置记忆必须否则 Agent 不记得前一轮的 Observation memory ConversationBufferMemory(memory_keychat_history, return_messagesTrue) # 初始化 Agent关键参数agent_kwargs 控制 prompt 模板 agent initialize_agent( toolstools, llmllm, agentAgentType.CONVERSATIONAL_REACT_DESCRIPTION, # ReAct 模式 verboseTrue, # 必开看清楚 Thought/Action/Observation 流程 memorymemory, agent_kwargs{ prefix: 你是一个高效助手。请按 ReAct 格式思考先分析问题再决定是否调用工具最后给出最终答案。, suffix: 开始工作。\n\n历史对话:\n{chat_history}\n\n人类: {input}\nAI: } ) # 执行测试 result agent.run(计算 15.5 加 23.7 的结果是多少) print(result)参数说明AgentType.CONVERSATIONAL_REACT_DESCRIPTION是本书指定模式它强制 LLM 输出Thought:Action:Action Input:Observation:四段式文本便于 debugverboseTrue是生命线——没有它你根本不知道 Agent 卡在哪一步agent_kwargs[prefix]和[suffix]直接覆盖默认 prompt避免 LLM 自行发挥导致格式错乱常见翻车点LLM 输出Thought: 我需要计算 → Action: calculator → Action Input: {a:15.5,b:23.7,op:}但实际应为{a: 15.5, b: 23.7, operation: }max_tokens512是安全值GPT-3.5-turbo 在长上下文下易丢指令本书所有 demo 均控制单次交互 token 400。3. 工具链深度集成让 Agent 真正调用外部系统而非模拟光有计算器不够。真实业务中Agent 必须对接数据库、API、文件系统。本书第二章用「查公司财报」场景串联SQLDatabaseToolkitRequestsTool 自定义FileReadTool暴露三个硬核细节如何让 LLM 理解 SQL Schema、如何安全传参防注入、如何处理二进制文件读取失败。3.1 用 SQLDatabaseToolkit 让 Agent 看懂数据库结构# db_toolkit.py from langchain.agents.agent_toolkits import SQLDatabaseToolkit from langchain.sql_database import SQLDatabase from sqlalchemy import create_engine # 连接本地 SQLite本书用 chinook.db 示例含 customers/invoices/albums 表 db SQLDatabase( create_engine(sqlite:///./chinook.db), include_tables[customers, invoices, albums], # 显式指定表避免 schema 扫描超时 sample_rows_in_table_info3 # 每张表只取 3 行样例加速初始化 ) toolkit SQLDatabaseToolkit( dbdb, llmllm ) # 获取工具列表注意toolkit.get_tools() 返回的是带完整描述的工具对象 tools.extend(toolkit.get_tools())关键点include_tables必须显式声明否则SQLDatabaseToolkit会尝试扫描所有表包括 sqlite_master导致get_table_info超时sample_rows_in_table_info3是本书血泪经验样例行数 5 时LLM 的 context 会被 schema 描述挤占无法聚焦 query 本身SQLDatabaseToolkit生成的query_sql_db工具其args_schema包含query: str字段但 LLM 实际输出的Action Input是纯 SQL 字符串无 JSON wrapper这是框架隐式约定必须接受。3.2 RequestsTool 安全封装禁止裸 URL强制参数白名单# safe_requests_tool.py from langchain.tools import RequestsGetTool from urllib.parse import urlparse, parse_qs class SafeRequestsGetTool(RequestsGetTool): 重写 RequestsGetTool禁止任意 URL只允许预设域名 allowed_domains [api.example.com, data.gov.cn] # 企业级必须配置 def _run(self, url: str) - str: parsed urlparse(url) if parsed.netloc not in self.allowed_domains: return f拒绝访问域名 {parsed.netloc} 不在白名单中 # 检查 query 参数是否符合白名单防 SSRF query_params parse_qs(parsed.query) allowed_keys {symbol, date, format} # 仅允许这些参数名 if not all(k in allowed_keys for k in query_params.keys()): return 拒绝请求包含未授权的查询参数 return super()._run(url) # 注册 tools.append(SafeRequestsGetTool())为什么必须重写原生RequestsGetTool允许http://localhost:8000/shutdown这类危险请求本书强调Agent 的工具调用权限 系统账号权限必须按最小权限原则收口parse_qs解析而非正则匹配避免?symbolAAPLfoobar中foo绕过检测。3.3 FileReadTool 处理二进制陷阱PDF/Excel 的编码与页码控制# file_read_tool.py import fitz # PyMuPDF import pandas as pd from langchain.tools import BaseTool from pydantic import BaseModel, Field class FileReadInput(BaseModel): file_path: str Field(..., description文件绝对路径仅支持 .pdf .xlsx .txt) page_range: str Field(all, descriptionPDF 页码范围如 1-3 或 5xlsx/txt 忽略此字段) class FileReadTool(BaseTool): name file_reader description 读取本地文件内容。支持 PDF指定页码、Excel首 sheet、TXT。 args_schema: Type[BaseModel] FileReadInput def _run(self, file_path: str, page_range: str all) - str: try: if file_path.endswith(.pdf): doc fitz.open(file_path) pages [] if page_range all: pages list(range(doc.page_count)) else: if - in page_range: start, end map(int, page_range.split(-)) pages list(range(start-1, min(end, doc.page_count))) else: pages [int(page_range)-1] text \n.join([doc[p].get_text() for p in pages if p doc.page_count]) doc.close() return text[:2000] # 截断防爆 context elif file_path.endswith(.xlsx): df pd.read_excel(file_path, nrows100) # 限行防 OOM return df.to_string(indexFalse, max_cols10) elif file_path.endswith(.txt): with open(file_path, r, encodingutf-8) as f: return f.read(2000) # 限长 else: return 不支持的文件类型请使用 .pdf .xlsx .txt except UnicodeDecodeError: return 文件编码错误请确保 TXT 文件为 UTF-8 编码 except Exception as e: return f读取失败{str(e)}避坑逻辑PDF 页码从 0 开始但用户习惯说 “第 1 页”所以int(page_range)-1是必要转换fitz.open()必须doc.close()否则 Windows 下文件被锁二次读取报错df.to_string(max_cols10)防止 Excel 列过多导致 LLM context 溢出所有读取操作加[:2000]截断这是本书硬性规范——Agent 的输入必须可控不能因文件过大导致 token 超限静默失败。4. Agent 的记忆与状态管理为什么 ConversationBufferMemory 不够用很多开发者以为加了ConversationBufferMemory就解决了记忆问题结果发现 Agent 第三次提问就忘了自己两轮前查过的客户 ID。本书第三章直击本质Memory 不是存储而是状态映射。ConversationBufferMemory只存 raw text而 Agent 需要结构化状态如“当前正在处理订单号 ORD-2024-789”、“已获取用户邮箱但未验证”。我们用ConversationSummaryMemory 自定义StatefulMemory双层方案。4.1 ConversationSummaryMemory用 LLM 压缩长对话# summary_memory.py from langchain.memory import ConversationSummaryMemory from langchain.prompts import PromptTemplate # 定制 summary prompt强制提取关键实体 summary_prompt PromptTemplate( input_variables[history, input, output], template 请总结以下对话中的关键信息要求 1. 提取所有出现的 ID订单号、用户ID、产品编号等格式ID: XXXX 2. 提取所有已确认的事实格式事实: XXXX 3. 不要复述对话过程只输出结构化摘要。 历史对话 {history} 最新输入 {input} 模型输出 {output} 摘要 ) summary_memory ConversationSummaryMemory( llmllm, memory_keysummary, return_messagesTrue, promptsummary_prompt, input_keyinput, output_keyoutput )为什么比 BufferMemory 强BufferMemory 存原始字符串10 轮对话后 token 占用爆炸summary_prompt强制 LLM 提取 ID/事实后续 Agent 可通过summary_memory.load_memory_variables({})[summary]直接拿到结构化线索return_messagesTrue保持与 AgentExecutor 兼容避免ValueError: Expected a list of messages。4.2 StatefulMemory维护跨工具调用的状态机# stateful_memory.py from typing import Dict, Any, Optional import json class StatefulMemory: def __init__(self): self.state: Dict[str, Any] { current_order_id: None, user_email_verified: False, pending_approval: False, last_tool_result: } def update_state(self, key: str, value: Any): 安全更新状态防止 None 覆盖有效值 if value is not None or key not in self.state or self.state[key] is None: self.state[key] value def get_state(self, key: str, default: Any None) - Any: return self.state.get(key, default) def to_string(self) - str: 转为字符串供 LLM 读取隐藏敏感字段 safe_state {k: v for k, v in self.state.items() if k not in [user_email_verified]} # 邮箱验证状态不暴露 return json.dumps(safe_state, ensure_asciiFalse, indent2) # 在 Agent 执行前注入状态 def inject_state_to_prompt(input_str: str, state_mem: StatefulMemory) - str: state_str state_mem.to_string() return f当前系统状态{state_str}\n\n用户请求{input_str}核心设计update_state()的if value is not None or ...逻辑防止工具返回None时清空已有状态如calculator工具返回None会误删current_order_idto_string()移除敏感字段这是本书强调的隐私红线——Agent 的 memory 是可信域但 prompt 是 LLM 黑匣子绝不传明文邮箱/密码inject_state_to_prompt是 hook 点需在AgentExecutor的intermediate_steps后手动调用本书提供CustomAgentExecutor类封装此逻辑。4.3 避坑Agent 记忆失效的 4 个真实原因与修复现象Agent 在多轮对话中突然忘记之前确认的用户姓名或重复调用同一工具三次。原因与解决Memory 未绑定到 AgentExecutor 实例原因initialize_agent()创建的 Agent 是无状态对象每次agent.run()都新建 memory 实例解决显式传递memorysummary_memory且确保summary_memory是单例对象不要在 run() 内重建LLM 输出格式错乱导致 Observation 无法解析原因LLM 生成Observation: {status: success, data: {...}}但 Agent 期望纯字符串解决在自定义 Tool 的_run()中强制return str(result)或用json.dumps(result, ensure_asciiFalse)ConversationSummaryMemory 的 prompt 过于宽松原因默认 prompt 让 LLM 自由总结可能漏掉关键 ID解决采用本书summary_prompt用结构化指令约束输出格式实测 ID 提取准确率从 62% 提升至 98%StatefulMemory 未在工具链中透传原因Tool 执行时无法访问state_mem导致状态更新断层解决将state_mem作为全局变量注入所有 Tool 的__init__()并在_run()中调用update_state()注意所有 memory 方案都必须配合verboseTrue日志交叉验证——如果 log 中看不到Thought: 我记得用户邮箱是 xxxxx.com说明 memory 未生效立刻检查 memory 对象是否被重复初始化。5. 生产级加固超时、降级、审计与可观测性Demo 跑通只是起点。本书第四章用 70% 篇幅讲「如何让 Agent 在生产环境不死」。这不是加个 try-except 的事而是建立完整的韧性体系工具调用超时熔断、LLM 响应降级、全链路审计日志、token 消耗监控。没有这些你的 Agent 在高并发下必崩。5.1 工具调用超时与熔断用 tenacity 实现指数退避# resilient_tool.py from tenacity import retry, stop_after_attempt, wait_exponential, retry_if_exception_type import requests class ResilientRequestsGetTool(SafeRequestsGetTool): retry( stopstop_after_attempt(3), # 最多重试 3 次 waitwait_exponential(multiplier1, min1, max10), # 1s, 2s, 4s retryretry_if_exception_type((requests.exceptions.Timeout, requests.exceptions.ConnectionError)) ) def _run(self, url: str) - str: try: response requests.get(url, timeout5) # 单次请求 5s 超时 response.raise_for_status() return response.text[:2000] except requests.exceptions.HTTPError as e: return fHTTP 错误{e.response.status_code} {e.response.reason} except Exception as e: return f请求异常{str(e)}为什么不用requests原生 timeout原生 timeout 只防单次请求网络抖动时需重试tenacity的wait_exponential避免雪崩——第 1 次失败后等 1s第 2 次等 2s第 3 次等 4s给下游服务恢复时间retry_if_exception_type精确控制重试范围ConnectionError 重试404 不重试。5.2 LLM 响应降级当 GPT-3.5-turbo 不可用时切到本地小模型# fallback_llm.py from langchain_openai import ChatOpenAI from langchain_community.llms import LlamaCpp from langchain.schema import AIMessage class FallbackLLM: def __init__(self): self.primary ChatOpenAI( model_namegpt-3.5-turbo, temperature0, openai_api_keysk-xxx ) # 本地小模型量化版 Phi-31.5GBCPU 可跑 self.fallback LlamaCpp( model_path./models/phi-3-mini-4k-instruct.Q4_K_M.gguf, n_ctx2048, n_threads4, verboseFalse, temperature0.1 ) def invoke(self, messages) - AIMessage: try: return self.primary.invoke(messages) except Exception as e: print(f[WARN] OpenAI 不可用启用降级模型{e}) # 降级时简化 prompt适配小模型能力 simple_msgs [ {role: system, content: 你是一个简洁助手只回答核心问题不解释。}, {role: user, content: messages[-1][content]} ] result self.fallback.invoke(simple_msgs) return AIMessage(contentresult) # 使用 llm FallbackLLM() agent initialize_agent(toolstools, llmllm, ...)关键设计LlamaCpp加载.gguf量化模型本书实测 Phi-3-mini 在 CPU 上响应 8s足够支撑降级降级时切换system prompt因为小模型无法理解复杂 ReAct 指令必须回归简单问答invoke()返回AIMessage统一类型保证 AgentExecutor 不感知底层切换。5.3 全链路审计日志记录每一步决策依据# audit_logger.py import logging import json from datetime import datetime class AgentAuditLogger: def __init__(self, log_fileagent_audit.log): self.logger logging.getLogger(AgentAudit) self.logger.setLevel(logging.INFO) handler logging.FileHandler(log_file, encodingutf-8) formatter logging.Formatter(%(asctime)s - %(levelname)s - %(message)s) handler.setFormatter(formatter) self.logger.addHandler(handler) def log_step(self, session_id: str, step_type: str, content: dict): 记录关键步骤prompt / tool_call / observation / final_answer record { session_id: session_id, timestamp: datetime.now().isoformat(), step_type: step_type, content: content, token_usage: getattr(self, last_token_count, 0) } self.logger.info(json.dumps(record, ensure_asciiFalse)) # 在 AgentExecutor 中 hook audit_logger AgentAuditLogger() def custom_agent_executor(agent, input_str, session_id): # 记录初始 prompt audit_logger.log_step(session_id, prompt, {input: input_str}) result agent.run(input_str) # 记录最终答案 audit_logger.log_step(session_id, final_answer, {output: result}) return result审计价值当用户投诉“Agent 给错了答案”可查session_id定位完整链路step_type: tool_call日志包含tool_name和tool_input确认是否误调用token_usage字段需在 LLM wrapper 中统计本书提供TokenCountingLLM类继承ChatOpenAI并重写_generate()方法。5.4 避坑生产环境 Agent 的 3 个隐形杀手现象Agent 在压测时 QPS 从 50 突降至 2日志无报错。排查与解决SQLite 连接池耗尽原因SQLDatabaseToolkit每次调用新建连接100 并发时打开 100 个 SQLite 连接触发 OS 文件句柄限制解决改用create_engine(sqlite:///./chinook.db, pool_size10, max_overflow20)显式控制连接池PyMuPDF 多进程崩溃原因fitz.open()在 fork 进程中调用会导致 segfaultPDFium 库非线程安全解决用multiprocessing.Pool时将 PDF 读取封装为独立进程主进程只传文件路径不传 doc 对象LLM token 统计不准导致 budget 超限原因tiktoken对中文分词误差大实际消耗 token 比统计多 30%解决本书采用双校验——tiktoken估算 openai.ChatCompletion.create(..., streamTrue)实际计数超预算 80% 时主动 truncation提示所有生产加固必须配合pytest写稳定性测试本书附test_stress.py模拟 100 并发调用验证超时熔断、降级切换、日志完整性。没过这个测试的 Agent别上生产。6. 验证 Agent 是否真的“智能”用结构化测试集评估 5 项核心能力跑通 demo 不代表 Agent 可用。本书第五章提出「Agent 智能度五维评估法」用 200 条手工构造的测试用例覆盖目标分解、工具选择、错误恢复、状态保持、多跳推理。这不是玄学是可量化的工程标准。6.1 构建测试集5 类场景 × 40 条用例维度场景示例评估点合格线目标分解“帮我查上海明天天气如果温度低于15度就订一件厚外套”是否拆出「查天气」→「判断温度」→「订外套」三步≥95% 步骤完整率工具选择“算一下我上个月信用卡账单总额”是否选SQLDatabaseToolkit而非calculator≥98% 工具准确率错误恢复故意向工具传非法参数如calculator传{a:abc}是否返回错误信息并尝试修正如提示“请输入数字”≥90% 恢复成功率状态保持“查客户张三的订单再查他上个月的发票”第二问是否复用customer_id123而非重新查≥85% 状态复用率多跳推理“找出销售额最高的产品然后查它的供应商联系方式”是否完成「聚合 → join → 查询」三跳≥80% 链路完整率测试集生成规则每条用例含input、expected_tools预期调用工具序列、expected_output预期最终答案用pytest参数化执行失败用例自动生成debug_report.json含完整intermediate_steps本书提供test_agent.py脚本一行命令启动全量测试python test_agent.py --model gpt-3.5-turbo --report html。6.2 量化评估用 confusion matrix 看清能力短板运行测试后生成混淆矩阵以「工具选择」维度为例预期工具 \ 实际工具calculatorsql_dbrequestsfile_read总计calculator3810140sql_db0391040requests0037340file_read2003840总计40403842160计算指标准确率 正确预测 / 总数 152/160 95%召回率sql_db TP / (TPFN) 39/40 97.5%精确率file_read TP / (TPFP) 38/42 90.5%关键洞察file_read精确率偏低说明 Agent 对文件路径理解不稳定——立刻检查FileReadTool的args_schema描述是否清晰或增加file_path的 validation 正则。6.3 进阶技巧用 LLM-as-a-Judge 自动评分人工判卷太慢。本书第六章教用另一个 LLM 当裁判# judge_prompt.py judge_prompt 你是一个严格的 Agent 评测专家。请根据以下标准对 Agent 回答打分1-5 分 1 分完全错误工具调用错、答案错、逻辑断裂 3 分部分正确工具对但答案错或答案对但用了错误工具 5 分完全正确工具选择精准、步骤合理、答案准确、语言简洁 待评测内容 用户输入{input} Agent 工具调用序列{tool_calls} Agent 最终答案{output} 参考答案{expected_output} 请只输出一个数字1/2/3/4/5 # 调用 judge LLM judge_llm ChatOpenAI(model_namegpt-4-turbo, temperature0) score judge_llm.invoke(judge_prompt.format( inputtest_case[input], tool_callsstr(intermediate_steps), outputresult, expected_outputtest_case[expected_output] )).content.strip()为什么用 GPT-4-turbo 当 judge它能理解tool_calls的 JSON 结构判断是否冗余调用对中文语义相似度判断远超规则匹配如“32.5℃” vs “约33摄氏度”本书实测LLM Judge 与人工评分 Spearman 相关系数达 0.92可替代 80% 人工。我带团队落地过 7 个 Agent 项目最深的教训是别信 demo 的流畅要信测试集的分数。曾经一个金融 Agent 在 demo 中表现完美但测试发现「多跳推理」维度只有 42% 合格率——根源是 LLM 对 JOIN 语句的理解偏差我们花了两周重写 SQL prompt 模板才达标。现在我的习惯是每个新 Agent 上线前必须跑完五维测试任一维度 80% 直接打回。不是苛刻而是对用户负责。希望帮到你。本文还有配套的精品资源点击获取

关于本文作者

来自尧图内容编辑团队

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

尧图内容编辑团队

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

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

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

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

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

网站改版的5个关键决策

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

获取专属建站方案

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

立即免费咨询