构建可靠、可扩展的AI智能体系统
Agent需要明确的任务目标和成功标准
Agent行为可预测、可干预、可回滚
Agent决策过程透明,可追踪调试
防止Agent做出有害或意外行为
| 维度 | 传统软件工程 | Agentic Engineering |
|---|---|---|
| 控制流 | 确定性执行 | 非确定性,LLM驱动 |
| 调试方式 | 断点、日志 | 轨迹追踪、LLM重放 |
| 测试策略 | 单元测试、集成测试 | 场景测试、LLM评估 |
| 部署方式 | 代码发布 | Agent配置 + 提示词更新 |
| 可靠性保证 | 形式化验证 | 护栏 + 人工监督 |
特点:简单直接,适合单一任务
特点:分工协作,适合复杂任务
| 技术 | 作用 |
|---|---|
| ReAct | 推理+行动交替 |
| CoT | 思维链推理 |
| ToT | 树状搜索规划 |
| Hiearchical | 层级任务分解 |
| 护栏类型 | 示例 |
|---|---|
| 输入过滤 | 敏感词检测、格式验证 |
| 输出过滤 | 内容安全检查 |
| 工具限制 | 权限控制、调用次数限制 |
| 预算限制 | Token限制、费用上限 |
| 观测维度 | 指标 |
|---|---|
| 执行轨迹 | 每步操作、耗时、结果 |
| LLM调用 | Token消耗、延迟、响应 |
| 工具使用 | 调用频率、成功率 |
| 质量评估 | 任务完成率、用户反馈 |
| 记忆类型 | 用途 |
|---|---|
| 短期记忆 | 当前对话上下文 |
| 长期记忆 | 跨会话经验积累 |
| 工作记忆 | 任务执行中间状态 |
| 知识检索 | RAG增强记忆 |
Agent检查输出质量,自我改进
Agent根据任务动态选择工具
模拟人类认知流程
多个Agent扮演不同专家角色
通过搜索找到解决方案
通过对话达成协作
| 类别 | 检查项 | 优先级 |
|---|---|---|
| 功能 | 任务定义清晰、成功标准明确 | P0 |
| 功能 | 覆盖主要场景、边界情况处理 | P0 |
| 安全 | 输入验证、输出过滤 | P0 |
| 安全 | 工具调用权限控制 | P0 |
| 可靠 | 错误处理、重试机制 | P1 |
| 可靠 | 降级方案(Agent失败时) | P1 |
| 观测 | 执行轨迹记录 | P1 |
| 观测 | 关键指标监控 | P1 |
| 性能 | 延迟控制(用户可接受) | P2 |
| 成本 | Token/费用监控 | P2 |
| 类型 | 说明 |
|---|---|
| 单元测试 | 工具函数、提示词模板 |
| 集成测试 | Agent与工具的交互 |
| E2E测试 | 完整任务执行流程 |
| LLM评估 | 输出质量自动评分 |
| 对抗测试 | 恶意输入、安全边界 |
| 指标 | 说明 | 计算公式 |
|---|---|---|
| 任务完成率 | 成功完成任务的比例 | 成功完成任务数 / 总任务数 |
| 步骤效率 | 完成任务的步数 | 平均步数或总步数 |
| 幻觉率 | 生成错误信息的比例 | 生成错误信息次数 / 总生成次数 |
| 工具调用准确率 | 正确使用工具的比例 | 正确使用工具次数 / 总工具调用次数 |
| 用户满意度 | 人工评估结果 | 调查问卷平均得分(如1-5分) |
| 层级 | 工具/框架 | 特点 |
|---|---|---|
| Agent框架 | LangGraph, AutoGen, CrewAI, LangChain Agents | 简化Agent开发流程 |
| LLM调用 | LangChain, LlamaIndex, OpenAI SDK | 统一接口、多模型支持 |
| 工具构建 | OpenAI Functions, JSON Schema | 结构化工具定义 |
| 编排协调 | LangGraph, Temporal, Dagster | 复杂工作流管理 |
| 可观测 | LangSmith, Arize, OpenTelemetry | 追踪、监控、调试 |
| 向量存储 | Pinecone, Chroma, Weaviate, FAISS | RAG记忆存储 |
from langchain_openai import ChatOpenAI
from langchain.agents import AgentExecutor, create_react_agent
from langchain.tools import tool
from langchain import hub
from pydantic import BaseModel
import re
llm = ChatOpenAI(model="gpt-4", temperature=0)
# 1. 定义工具
class CalculatorInput(BaseModel):
expression: str
@tool(args_schema=CalculatorInput)
def calculate(expression: str) -> str:
"""执行数学计算"""
try:
result = eval(expression)
return str(result)
except Exception as e:
return f"计算错误: {e}"
@tool
def search_web(query: str) -> str:
"""搜索网络信息"""
return f"搜索结果: {query}的相关信息"
tools = [calculate, search_web]
# 2. 构建Agent
prompt = hub.pull("hwchase17/react")
agent = create_react_agent(llm, tools, prompt)
agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)
# 3. 执行任务
result = agent_executor.invoke({"input": "计算 25 * 4 + 10"})
print(f"结果: {result['output']}")
from langgraph.graph import StateGraph, END
from langchain_openai import ChatOpenAI
from typing import TypedDict, List
llm = ChatOpenAI(model="gpt-4", temperature=0)
# 1. 定义状态
class AgentState(TypedDict):
task: str
research: str
analysis: str
final_answer: str
# 2. 定义Agent节点
def researcher(state: AgentState) -> AgentState:
"""研究Agent:收集信息"""
response = llm.invoke(f"研究以下问题: {state['task']}")
return {"research": response.content}
def analyzer(state: AgentState) -> AgentState:
"""分析Agent:深度分析"""
response = llm.invoke(f"基于以下研究进行分析:\n{state['research']}")
return {"analysis": response.content}
def writer(state: AgentState) -> AgentState:
"""写作Agent:生成最终答案"""
response = llm.invoke(f"基于以下分析写一个清晰的回答:\n{state['analysis']}")
return {"final_answer": response.content}
# 3. 构建图
workflow = StateGraph(AgentState)
workflow.add_node("researcher", researcher)
workflow.add_node("analyzer", analyzer)
workflow.add_node("writer", writer)
workflow.set_entry_point("researcher")
workflow.add_edge("researcher", "analyzer")
workflow.add_edge("analyzer", "writer")
workflow.add_edge("writer", END)
graph = workflow.compile()
# 4. 执行
result = graph.invoke({"task": "AI的未来发展趋势是什么?"})
print(result["final_answer"])
from langchain_openai import ChatOpenAI
from langchain.chains import ConversationChain
from langchain.memory import ConversationBufferMemory
from langchain.prompts import ChatPromptTemplate, MessagesPlaceholder
llm = ChatOpenAI(model="gpt-4", temperature=0.7)
# 1. 带记忆的对话Agent
memory = ConversationBufferMemory(
return_messages=True,
memory_key="history"
)
prompt = ChatPromptTemplate.from_messages([
("system", "你是一个有帮助的助手,记住之前的对话内容。"),
MessagesPlaceholder(variable_name="history"),
("human", "{input}")
])
conversation = ConversationChain(
llm=llm,
prompt=prompt,
memory=memory,
verbose=False
)
# 2. 对话演示
print(conversation.invoke({"input": "我叫张三"}))
print(conversation.invoke({"input": "我叫什么名字?"}))
print(conversation.invoke({"input": "我喜欢Python编程"}))
print(conversation.invoke({"input": "我刚才说我喜欢什么?"}))
from langchain.callbacks.base import BaseCallbackHandler
from langchain_openai import ChatOpenAI
from langchain.agents import AgentExecutor, create_react_agent
from langchain.tools import tool
from langchain import hub
import time
# 1. 自定义回调处理器(可观测性)
class AgentCallbackHandler(BaseCallbackHandler):
def __init__(self):
self.steps = []
def on_llm_start(self, serialized, prompts, **kwargs):
print(f"📝 LLM开始处理...")
def on_llm_end(self, response, **kwargs):
print(f"✅ LLM完成,耗时: 短")
def on_tool_start(self, serialized, input_str, **kwargs):
print(f"🔧 调用工具: {serialized['name']}")
def on_tool_end(self, output, **kwargs):
print(f"📊 工具输出长度: {len(output)}")
# 2. 构建带观测的Agent
@tool
def get_weather(city: str) -> str:
"""获取城市天气"""
return f"{city}的天气是晴天,25度"
tools = [get_weather]
prompt = hub.pull("hwchase17/react")
agent = create_react_agent(ChatOpenAI(model="gpt-4"), tools, prompt)
agent_executor = AgentExecutor(
agent=agent,
tools=tools,
callbacks=[AgentCallbackHandler()],
verbose=True
)
# 3. 执行并观测
agent_executor.invoke({"input": "北京的天气怎么样?"})
from langchain_openai import ChatOpenAI
from langchain.agents import tool
from langchain.prompts import PromptTemplate
from langchain_core.output_parsers import StrOutputParser
llm = ChatOpenAI(model="gpt-4", temperature=0)
@tool
def search_code_documentation(query: str) -> str:
"""搜索编程文档"""
return f"关于{query}的官方文档说明"
@tool
def run_python_code(code: str) -> str:
"""运行Python代码"""
try:
exec(code)
return "代码执行成功"
except Exception as e:
return f"错误: {e}"
tools = [search_code_documentation, run_python_code]
# ReAct提示词
react_prompt = """你是一个ReAct Agent。请按以下格式思考:
Thought: 你需要思考应该做什么
Action: 工具名称 (如果需要工具调用)
Action Input: 工具输入 (如果需要工具调用)
Observation: 工具返回的结果 (如果调用了工具)
最后给出最终答案。
可用工具: {tool_names}
问题: {input}
"""
# ReAct执行循环
def react_agent(query: str, max_iterations: int = 5):
current_query = query
history = []
for i in range(max_iterations):
# 构建提示
prompt = react_prompt.format(
tool_names=[t.name for t in tools],
input=current_query
)
# 添加历史
if history:
prompt += "\n\n历史:\n" + "\n".join(history)
response = llm.invoke(prompt).content
# 解析响应
if "Final Answer" in response:
return response.split("Final Answer:")[1].strip()
# 提取Action
if "Action:" in response:
action_line = response.split("Action:")[1].split("\n")[0].strip()
action_name = action_line.split("(")[0].strip()
action_input = action_line.split("(")[1].replace(")", "").strip()
# 调用工具
for tool in tools:
if tool.name == action_name:
result = tool.invoke(action_input)
history.append(f"Action: {action_name}({action_input})")
history.append(f"Observation: {result}")
current_query = f"基于以上信息,继续回答: {query}"
break
return "达到最大迭代次数"
# 测试ReAct Agent
result = react_agent("如何用Python计算1到100的和?")
print(result)