0d14c98cf4cae83eb4432d3dcf49d1d04754031d
LLM Tool Proxy
1. 概述 (Overview)
本项目是一个基于 FastAPI 实现的智能LLM(大语言模型)代理服务。其核心功能是拦截发往LLM的API请求,动态地将客户端定义的tools(工具)信息注入到提示词(Prompt)中,然后将LLM返回的结果进行解析,将其中可能包含的工具调用(Tool Call)指令提取出来,最后以结构化的格式返回给调用者。
这使得即使底层LLM原生不支持工具调用参数,我们也能通过提示工程的方式赋予其使用工具的能力。
2. 设计原则 (Design Principles)
本程序在设计上严格遵循了以下原则:
- 高内聚 (High Cohesion): 业务逻辑被集中在服务层 (
app/services.py) 中,与API路由和数据模型分离。 - 低耦合 (Low Coupling):
- API层 (
app/main.py) 只负责路由和请求校验,不关心业务实现细节。 - 通过依赖注入 (
Depends) 获取配置,避免了全局状态。 - LLM调用被抽象为独立的函数,方便未来切换不同的LLM后端或在测试中使用模拟(Mock)实现。
- API层 (
- 可测试性 (Testability): 项目包含了完整的单元测试和集成测试 (
tests/),使用pytest和TestClient来确保每个模块的正确性和整体流程的稳定性。
3. 项目结构 (Project Structure)
.
├── app/ # 核心应用代码
│ ├── core/ # 配置管理
│ │ └── config.py
│ ├── main.py # FastAPI 应用实例和 API 路由
│ ├── models.py # Pydantic 数据模型
│ └── services.py # 核心业务逻辑
├── tests/ # 测试代码
│ └── test_main.py
├── .env # 环境变量文件 (需手动创建)
├── .gitignore # Git 忽略文件
├── README.md # 本文档
└── .venv/ # Python 虚拟环境 (由 uv 创建)
4. 核心逻辑详解 (Core Logic)
4.1. 提示词注入 (Prompt Injection)
- 实现函数:
app.services.inject_tools_into_prompt - 策略:
- 将客户端请求中
tools列表(JSON数组)序列化为格式化的JSON字符串。 - 创建一个新的、
role为system的独立消息。 - 此消息包含明确的指令,告诉LLM它拥有哪些工具以及如何通过特定的格式来调用它们。
- 调用格式约定: 指示LLM在需要调用工具时,必须输出一个
<tool_call>{...}</tool_call>的XML标签,其中包含一个带有name和arguments字段的JSON对象。 - 这个系统消息被插入到原始消息列表的第二个位置(索引1),然后整个修改后的消息列表被发送到真实的LLM后端。
- 将客户端请求中
- 目的: 对调用者透明,将工具使用的“契约”通过上下文传递给LLM。
4.2. 响应解析 (Response Parsing)
- 实现函数:
app.services.parse_llm_response - 策略:
- 使用正则表达式 (
re.search) 在LLM返回的纯文本响应中查找<tool_call>...</tool_call>标签。 - 如果找到,它会提取标签内的JSON字符串,并将其解析为一个结构化的
ToolCall对象。此时,返回给客户端的ResponseMessage中tool_calls字段将被填充,而content字段可能为None。 - 如果未找到标签,则将LLM的全部响应视为常规的文本内容,填充
content字段。
- 使用正则表达式 (
- 目的: 将LLM的非结构化(或半结构化)输出,转换为客户端可以轻松处理的、定义良好的结构化数据。
5. 配置管理 (Configuration)
- 配置文件为根目录下的
.env。 app/core/config.py中的get_settings函数通过依赖注入的方式在每次请求时加载环境变量,确保配置的实时性和在测试中的灵活性。- 必需变量:
REAL_LLM_API_URL: 真实LLM后端的地址。REAL_LLM_API_KEY: 用于访问真实LLM的API密钥。
6. 如何运行与测试 (Usage)
6.1. 环境设置
# 创建虚拟环境
uv venv
# 安装依赖
uv pip install fastapi uvicorn httpx pytest
6.2. 运行开发服务器
uvicorn app.main:app --reload
服务将运行在 http://127.0.0.1:8000。
6.3. 运行测试
# 使用 .venv 中的 python 解释器执行 pytest
.venv/bin/python -m pytest
7. API 端点示例 (API Example)
端点: POST /v1/chat/completions
请求示例 (带工具):
curl -X POST "http://127.0.0.1:8000/v1/chat/completions" \
-H "Content-Type: application/json" \
-d '{
"messages": [
{"role": "user", "content": "What is the weather in San Francisco?"}
],
"tools": [
{
"type": "function",
"function": {
"name": "get_weather",
"description": "Get weather for a city",
"parameters": {}
}
}
]
}'
8. 未来升级方向 (Future Improvements)
- 支持多种LLM后端: 修改
call_llm_api_real函数,使其能根据请求参数或配置选择不同的LLM提供商。 - 更灵活的工具调用格式: 支持除XML标签外的其他格式,例如纯JSON输出模式。
- 流式响应 (Streaming): 支持LLM的流式输出,并实时解析和返回给客户端。
- 错误处理增强: 针对不同的LLM API错误码和网络问题,提供更精细的错误反馈。
Description
Languages
Python
99.7%
Dockerfile
0.3%