96SEO 2026-08-06 10:36 6
话说回来,
上一章我们完成了 Today 和 Coach Chat 的行动闭环:前端或调用方发来使用者消息。Spring 后端补齐可信使用者上下文,再把请求交给 Python Agent Service。
这一章我们将进一步完善 Agent Service。引入 Tool Registry,让模型仅仅提出需求,而真正的计算和决策由后端安全、可测试的工具完成。

学完本章后你会得到以下成果:
services/agent-service/app/tools.py 中定义了两个可被 Agent 调用的工具:
calculate_macro_target: 热量和三大营养素。generate_training_plan: 根据目标、训练频率、器械与伤病标记生成训练结构。execute_tool 决定到底执行哪一个函数。tests/test_tools.py 锁住两条关键行为:
AgentService.chat 的工具调用链路更加清晰:
使用者痛点:
本章节继续沿用前几章复制标记:
: 在终端复制运行。其实,: 把完整代码复制到指定文件。: 用于理解错误写法或最小版本,不要写进项目中。提示: 如果你是从空目录跟着课程做,把上面绝对方法替换成自己的项目方法即可。
1️⃣ 模型直接给出数值存在误差与极限风险 2️⃣ 无法在单元测试中锁定业务逻辑 3️⃣ 难以实现可复用、安全可审计的接口
User: 我 175cm 80kg 想减脂但不想掉力量。一周练
AIGC Reply: 你每天吃 .
cd services/agent-service
PYTHONPATH=. pytest tests/test_tools.py
| 痛点 | 为什么关键 | 本章节方法 |
|---|---|---|
| 精确度与安全 | 错误建议可能导致健康损害或资金浪费 | 使用 Pydantic 校验 + 预设 safetyNote |
| 不可测性 | 难以验证逻辑正确性 | 单元测试锁定关键业务规则 |
| 功能边界模糊 | 任意函数被执行带来安全隐患 | 白名单 execute_tool + 限制动态加载 |
python
class MacroTargetArgs:
height_cm: float = Field
weight_kg: float = Field
从goal来看,str
training_days: int = Field
activity_level : str = "moderate"
注解
- gt / lt 等限定字段防止无效输入
- 默认值提供健壮性
python
TOOL_SCHEMAS : list] =
注解 - 给 LLM 明确说明可以请求哪些功能 - 不含业务细节,仅描述形状
python
def calculate_macro_target -> dict:
parsed = MacroTargetArgs.model_validate
multiplier = ... # based on activity_level
maintenance = int
deficit_factor = -0.15 if 'fat' in parsed.goal.lower else 0.
calories = int)
protein_g = int
fat_g = int
carbs_g = max / ...))
return {"calories": calories。"proteinG": protein_g,"carbsG": carbs_g,"fatG": fat_g,"safetyNote":"热量调整不超过估算维持热量的 %,避免极端节食"}
execute_tool
python
def execute_tool -> dict:
再看try,if name=="calculate_macro_target":
return calculate_macro_target
if name=="generate_training_plan":
return generate_training_plan
except ValidationError as exc:
return {"error":"tool_validation_failed","details":exc.errors}
return {"error":"unknown_tool","tool":name}
注解 - 防止任意函数被触发 - 捕获校验错误并返回结构化信息
python from app.tools import calculatemacrotarget,generatetrainingplan
def testmacrotargetlimitsdeficit: result = calculatemacrotarget({ "heightcm":170,"weightkg":80,"goal":"减脂但不掉力量","trainingdays":5}) assert result == expectedcaloriesvalue assert result == expectedprotein_value assert "极端节食" in result
def testtrainingplandowngradeskneerisk: result = generatetrainingplan({ 说到"goal","减脂","trainingdays":5,"injury_flags":}) assert any assert "疼痛" in result
为什么这样做? - 确保主要公式始终如初 - 验证伤病降级机制正确触发
python first = await self.client.chat
if first.tool_calls: messages.append
for call in first.toolcalls: function=dict or {}) name=function.get or "" rawargs=function.get or "{}" args=json.loads if isinstance else raw_args
result=execute_tool
messages.append({
从"role"来看。"tool",...
})
关键步骤
1. 第一轮 chat 给 LLM 工具列表。2. 若有 tool_calls 则解析并通过 execute_tool 执行。3. 将结果作为 消息追加回对话,以便第二轮 chat 使用。不过,
ModuleNotFoundError: app not found.
通常是因为没进入 services/agent-service 或忘记设置 PYTHONPATH。
cd services/agent-service && PYTHONPATH=. pytest tests/test_tools.py。ValidationError: 参数非法.
直接调用 tool 函数时会抛异常,但="">
| 任务项<\/th> | 预期结果<\/th> | ||
|---|---|---|---|
$ PYTHONPATH=. pytest tests/testtools.py<\/pre> | service.py<\/pre>
AgentService 主分支正常。无网络依赖<\/td> | ||
| 手动模拟案例 normal macro invalid weight unknown tool | 分别输出对应错误码与成功结果<\/td> | ||
作为专业的SEO优化服务提供商,我们致力于通过科学、系统的搜索引擎优化策略,帮助企业在百度、Google等搜索引擎中获得更高的排名和流量。我们的服务涵盖网站结构优化、内容优化、技术SEO和链接建设等多个维度。
| 服务项目 | 基础套餐 | 标准套餐 | 高级定制 |
|---|---|---|---|
| 关键词优化数量 | 10-20个核心词 | 30-50个核心词+长尾词 | 80-150个全方位覆盖 |
| 内容优化 | 基础页面优化 | 全站内容优化+每月5篇原创 | 个性化内容策略+每月15篇原创 |
| 技术SEO | 基本技术检查 | 全面技术优化+移动适配 | 深度技术重构+性能优化 |
| 外链建设 | 每月5-10条 | 每月20-30条高质量外链 | 每月50+条多渠道外链 |
| 数据报告 | 月度基础报告 | 双周详细报告+分析 | 每周深度报告+策略调整 |
| 效果保障 | 3-6个月见效 | 2-4个月见效 | 1-3个月快速见效 |
我们的SEO优化服务遵循科学严谨的流程,确保每一步都基于数据分析和行业最佳实践:
全面检测网站技术问题、内容质量、竞争对手情况,制定个性化优化方案。
基于用户搜索意图和商业目标,制定全面的关键词矩阵和布局策略。
解决网站技术问题,优化网站结构,提升页面速度和移动端体验。
创作高质量原创内容,优化现有页面,建立内容更新机制。
获取高质量外部链接,建立品牌在线影响力,提升网站权威度。
持续监控排名、流量和转化数据,根据效果调整优化策略。
基于我们服务的客户数据统计,平均优化效果如下:
我们坚信,真正的SEO优化不仅仅是追求排名,而是通过提供优质内容、优化用户体验、建立网站权威,最终实现可持续的业务增长。我们的目标是与客户建立长期合作关系,共同成长。
Demand feedback