1. 遇到问题的章节 / Affected Chapter
Chapter7.4
2. 问题类型 / Issue Type
代码错误 / Code Error
3. 具体问题描述 / Problem Description
问题现象
my_simple_agent.py 中的 MySimpleAgent 类在调用 LLM 后,错误地将 LLMResponse 对象当作字符串处理,导致多个类型错误。
错误代码分析
错误位置 1:run 方法(第 51行)
def run(self, input_text: str, max_tool_iterations: int = 3, **kwargs) -> str:
if not self.enable_tool_calling:
response = self.llm.invoke(messages, **kwargs) # ← 返回 LLMResponse 对象
#print(response.content)
self.add_message(Message(input_text, "user"))
# ❌ 错误:直接传递 LLMResponse 对象给 Message
self.add_message(Message(response, "assistant"))
print(f"✅ {self.name} 响应完成")
return response
错误位置 2:_run_with_tools 方法(第 92 行)
def _run_with_tools(self, messages: list, input_text: str, max_tool_iterations: int, **kwargs) -> str:
while current_iteration < max_tool_iterations:
response = self.llm.invoke(messages, **kwargs) # ← 返回 LLMResponse 对象
# ❌ 错误:直接传递 LLMResponse 对象给 _parse_tool_calls
tool_calls = self._parse_tool_calls(response)
错误位置 3:_run_with_tools 方法(第 98、104 行)
if tool_calls:
tool_results = []
clean_response = response # ❌ 错误:赋值为 LLMResponse 对象,不是字符串
for call in tool_calls:
result = self._execute_tool_call(call['tool_name'], call['parameters'])
tool_results.append(result)
# ❌ 错误:LLMResponse 对象没有 replace() 方法
clean_response = clean_response.replace(call['original'], "")
根本原因分析
LLMResponse 类定义(有 __str__() 方法)
# hello_agents/core/llm_response.py
@dataclass
class LLMResponse:
content: str
model: str
# ... 其他字段
def __str__(self) -> str:
"""向后兼容:直接打印返回content"""
return self.content # ✅ 定义了 __str__
为什么 __str__() 没有被自动调用?
| 调用场景 |
是否调用 __str__() |
原因 |
print(response) |
✅ 是 |
print 会自动调用 str() |
str(response) |
✅ 是 |
显式类型转换 |
f"{response}" |
✅ 是 |
f-string 自动调用 str() |
re.findall(pattern, response) |
❌ 否 |
不会自动转换,直接检查类型 |
re.findall() 的行为
import re
# re.findall() 会检查参数类型
matches = re.findall(pattern, text) # text 必须是 str 或 bytes
# 如果传入 LLMResponse 对象
matches = re.findall(pattern, llm_response) # ❌ TypeError
错误堆栈
####第一个错误(第51行)
Traceback (most recent call last):
File "f:\code\hello-agents\code\chapter7\test_simple_agent.py", line 21, in <module>
response1 = basic_agent.run("你好,请介绍一下自己")
~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^
File "f:\code\hello-agents\code\chapter7\my_simple_agent.py", line 51, in run
self.add_message(Message(response, "assistant"))
~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^
File "D:\ProgramData\anaconda3\envs\hello-agent\Lib\site-packages\hello_agents\core\message.py", line 18, in __init__
super().__init__(
~~~~~~~~~~~~~~~~^
content=content,
^^^^^^^^^^^^^^^^
...<2 lines>...
metadata=kwargs.get('metadata', {})
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
)
^
File "D:\ProgramData\anaconda3\envs\hello-agent\Lib\site-packages\pydantic\main.py", line 250, in __init__
validated_self = self.__pydantic_validator__.validate_python(data, self_instance=self)
pydantic_core._pydantic_core.ValidationError: 1 validation error for Message
content
Input should be a valid string [type=string_type, input_value=LLMResponse(model=deepsee...210, content_length=353), input_type=LLMResponse]
For further information visit https://errors.pydantic.dev/2.12/v/string_type
第二个错误(第 92 行)
Traceback (most recent call last):
File "f:\code\hello-agents\code\chapter7\test_simple_agent.py", line 38, in <module>
response2 = enhanced_agent.run("请帮我计算 15 * 8 + 32")
~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^
File "f:\code\hello-agents\code\chapter7\my_simple_agent.py", line 56, in run
return self._run_with_tools(messages, input_text, max_tool_iterations, **kwargs)
File "f:\code\hello-agents\code\chapter7\my_simple_agent.py", line 92, in _run_with_tools
tool_calls = self._parse_tool_calls(response)
File "f:\code\hello-agents\code\chapter7\my_simple_agent.py", line 134, in _parse_tool_calls
matches = re.findall(pattern, text)
File "D:\ProgramData\anaconda3\envs\hello-agent\Lib\re\__init__.py", line 278, in findall
return _compile(pattern, flags).findall(string)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^
TypeError: expected string or bytes-like object, got 'LLMResponse'
第三个错误(第 104 行,修复第一个后出现)
Traceback (most recent call last):
File "f:\code\hello-agents\code\chapter7\test_simple_agent.py", line 38, in <module>
response2 = enhanced_agent.run("请帮我计算 15 * 8 + 32")
~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^
File "f:\code\hello-agents\code\chapter7\my_simple_agent.py", line 56, in run
return self._run_with_tools(messages, input_text, max_tool_iterations, **kwargs)
File "f:\code\hello-agents\code\chapter7\my_simple_agent.py", line 104, in _run_with_tools
clean_response = clean_response.replace(call['original'], "")
^^^^^^^^^^^^^^^^^^^^^^
AttributeError: 'LLMResponse' object has no attribute 'replace'
### 4. 问题重现材料 / Reproduction Materials
### 错误文件路径
`F:\code\hello-agents\code\chapter7\my_simple_agent.py`
### 测试代码
```python
# test_simple_agent.py (第 24-39 行)
print("=== 测试2:工具增强对话 ===")
tool_registry = ToolRegistry()
calculator = CalculatorTool()
tool_registry.register_tool(calculator)
enhanced_agent = MySimpleAgent(
name="增强助手",
llm=llm,
system_prompt="你是一个智能助手,可以使用工具来帮助用户。",
tool_registry=tool_registry,
enable_tool_calling=True
)
response2 = enhanced_agent.run("请帮我计算 15 * 8 + 32") # ← 触发错误
print(f"工具增强响应: {response2}\n")
预期行为 vs 实际行为
预期行为
response.content 被正确提取并传递给 _parse_tool_calls()
- 正则表达式解析成功,找到工具调用标记
- 字符串替换操作成功执行
- 工具正常调用并返回结果
实际行为
LLMResponse 对象被直接传递,触发 TypeError
- 或者字符串操作失败,触发
AttributeError
环境信息
- Python 版本: 3.13.11
- hello-agents 版本: 1.0.0
- 操作系统: Windows 11 (Version 10.0.26200)
5. 补充信息 / Additional Information
为什么 LLMResponse 定义了 __str__() 但不起作用?
Python 的 __str__() 调用规则
class LLMResponse:
def __str__(self):
return self.content
# ✅ 会调用 __str__()
print(response) # → "response.content"
str(response) # → "response.content"
f"{response}" # → "response.content"
# ❌ 不会调用 __str__()
len(response) # → TypeError
re.findall(pattern, response) # → TypeError (直接检查类型)
response.replace(...) # → AttributeError (直接查找方法)
关键点: __str__() 只在 Python 需要字符串表示时被调用,但不会在期望特定类型时自动转换。
正确的修复方案
直接使用 response.content 属性(推荐)
# 修复位置 1:第 92 行
self.add_message(Message(response.content, "assistant")) # ✅ 使用 content 属性
# 修复位置 1:第 92 行
tool_calls = self._parse_tool_calls(response.content) # ✅ 使用 content 属性
# 修复位置 2:第 98 行
clean_response = response.content # ✅ 使用 content 属性
### 确认事项 / Verification
- [x] 我已阅读过相关章节的文档 / I have read the relevant chapter documentation
- [x] 我已搜索过现有的Issues,确认此问题未被报告 / I have searched existing Issues and confirmed this hasn't been reported
- [x] 我已尝试过基本的故障排除(如重启、重新安装依赖等) / I have tried basic troubleshooting (restart, reinstall dependencies, etc.)
1. 遇到问题的章节 / Affected Chapter
Chapter7.4
2. 问题类型 / Issue Type
代码错误 / Code Error
3. 具体问题描述 / Problem Description
问题现象
my_simple_agent.py中的MySimpleAgent类在调用 LLM 后,错误地将LLMResponse对象当作字符串处理,导致多个类型错误。错误代码分析
错误位置 1:
run方法(第 51行)错误位置 2:
_run_with_tools方法(第 92 行)错误位置 3:
_run_with_tools方法(第 98、104 行)根本原因分析
LLMResponse 类定义(有
__str__()方法)为什么
__str__()没有被自动调用?__str__()print(response)str()str(response)f"{response}"str()re.findall(pattern, response)re.findall()的行为错误堆栈
####第一个错误(第51行)
第二个错误(第 92 行)
第三个错误(第 104 行,修复第一个后出现)
预期行为 vs 实际行为
预期行为
response.content被正确提取并传递给_parse_tool_calls()实际行为
LLMResponse对象被直接传递,触发TypeErrorAttributeError环境信息
5. 补充信息 / Additional Information
为什么 LLMResponse 定义了
__str__()但不起作用?Python 的
__str__()调用规则关键点:
__str__()只在 Python 需要字符串表示时被调用,但不会在期望特定类型时自动转换。正确的修复方案
直接使用
response.content属性(推荐)