在当今AI技术快速发展的背景下,能够自主调用工具完成复杂任务的AI Agent正成为行业热点。与普通聊天机器人不同,一个真正的AI Agent应该具备环境感知、自主决策和工具调用的能力。本文将基于LangChain框架,手把手教你构建一个能够调用RAG知识库和计算器工具的实用AI Agent。
我最近在实际项目中开发了一个公司内部使用的AI助手,它能够查询机密文档并执行精确计算。通过这个案例,我将分享Agent开发的核心技术要点、常见陷阱以及安全防护措施。无论你是AI开发者还是技术管理者,都能从中获得可直接落地的实践经验。
一个完整的AI Agent通常由以下四个关键部分组成:
LLM(大语言模型):负责自然语言理解和生成,是Agent的"大脑"。在示例中我们使用通义千问(qwen-plus)作为基础模型。
记忆系统:
规划模块:控制任务执行流程,决定何时调用哪个工具。在LangChain中这部分由框架自动处理。
工具集:Agent可以调用的外部函数,如示例中的计算器和文档搜索工具。
提示:工具函数必须返回字符串类型,这是LangChain的强制要求。所有工具调用结果都会被转换为文本形式供LLM处理。
工具调用是Agent区别于普通聊天机器人的核心能力。在LangChain中实现工具调用需要三个步骤:
工具调用的典型工作流程如下:
code复制用户提问 -> LLM分析 -> 决定调用工具 -> 执行工具 -> 结果返回LLM -> 生成最终回复
首先需要安装必要的Python包:
bash复制pip install langchain-core langchain-community faiss-cpu dashscope
建议使用Python 3.8+环境,并准备好通义千问的API密钥(DASHSCOPE_API_KEY)。
原始示例中使用eval存在严重安全隐患。以下是改进后的安全实现:
python复制import re
from operator import add, sub, mul, truediv
@tool
def safe_calculator(expression: str) -> str:
"""
安全计算数学表达式(仅支持基本四则运算)。
示例:
- 输入: "2 + 3 * 4"
- 输出: "14.0"
"""
if not re.match(r'^[\d\s+\-*/.()]+$', expression):
return "错误: 表达式包含非法字符"
try:
# 使用更安全的计算方式
operators = {'+': add, '-': sub, '*': mul, '/': truediv}
# 实际实现中应添加更完善的解析逻辑
return str(eval(expression, {'__builtins__': None}, operators))
except Exception as e:
return f"计算错误: {e}"
原始示例中的文本分块参数(chunk_size=25)过小,实际项目中建议:
python复制text_splitter = RecursiveCharacterTextSplitter(
chunk_size=500, # 更适合文档检索的块大小
chunk_overlap=100,
separators=["\n\n", "\n", "。", "!", "?", ";"]
)
对于生产环境,建议使用更健壮的向量数据库如Pinecone或Milvus,而非本地FAISS。
Agent的核心控制逻辑需要注意以下几点:
改进后的主循环结构:
python复制MAX_ITERATIONS = 5 # 最大迭代次数
def run_agent(query: str):
tool_maps = {
"rag_search": rag_search,
"calculator": safe_calculator # 使用安全版本
}
llm = ChatTongyi(model_name="qwen-plus")
tool_llm = llm.bind_tools(tools=list(tool_maps.values()))
messages = [HumanMessage(content=query)]
for iteration in range(MAX_ITERATIONS):
try:
response = tool_llm.invoke(messages)
messages.append(response)
if not response.tool_calls:
return response.content
for tool_call in response.tool_calls:
# 工具调用处理逻辑
...
except Exception as e:
return f"Agent执行出错: {str(e)}"
return "达到最大处理轮数,请简化您的问题"
生产环境推荐的安全架构:
code复制用户请求 -> 输入验证层 -> 权限检查 -> Agent处理 -> 输出过滤 -> 审计记录
添加详细的日志记录:
python复制def log_tool_call(func):
def wrapper(*args, **kwargs):
print(f"TOOL CALL: {func.__name__} with args: {args}, {kwargs}")
result = func(*args, **kwargs)
print(f"TOOL RESULT: {result[:200]}...") # 限制日志长度
return result
return wrapper
# 装饰工具函数
@tool
@log_tool_call
def rag_search(query: str) -> str:
...
| 错误现象 | 可能原因 | 解决方案 |
|---|---|---|
| 工具未被调用 | 文档字符串不完整 | 确保工具描述包含示例 |
| 错误工具被调用 | 工具描述相似度过高 | 差异化各工具的描述 |
| 无限循环 | LLM持续要求工具 | 限制迭代次数,优化prompt |
| 性能低下 | 工具响应慢 | 添加超时机制,优化工具实现 |
在绑定工具时添加系统提示:
python复制from langchain_core.prompts import ChatPromptTemplate
system_prompt = """你是一个专业的企业助手,请遵守以下规则:
1. 只在必要时调用工具
2. 优先使用知识库查询
3. 数学计算必须使用计算器工具
"""
prompt = ChatPromptTemplate.from_messages([
("system", system_prompt),
("human", "{input}")
])
tool_llm = llm.bind_tools(tools=list(tool_maps.values()), prompt=prompt)
通过组合多个工具实现复杂业务流程:
python复制@tool
def business_workflow(question: str) -> str:
"""
处理复杂业务流程:
1. 先查询知识库获取基础信息
2. 如有需要则执行计算
3. 生成综合报告
"""
# 实现具体工作流逻辑
...
构建多个专业Agent协同工作的系统:
code复制用户 -> 路由Agent -> 技术Agent/财务Agent/HRAgent -> 结果汇总
实现Agent的自我优化:
在实际项目中,我发现Agent开发最难的不是技术实现,而是设计合理的工具边界和安全控制。建议在初期就建立完善的测试用例,覆盖各种正常和异常场景。另外,工具描述文档的质量直接影响调用准确性,需要像编写API文档一样认真对待。