Update README and HiAgent API guide with model list and examples#4
Update README and HiAgent API guide with model list and examples#4Bigzhangbig wants to merge 1 commit intoyht0511:mainfrom
Conversation
…,优化设置文件以兼容新旧凭证模式。
There was a problem hiding this comment.
Pull request overview
该 PR 旨在补齐 HiAgent 官方文档已完善后的“直连 API”接入方式:在代码侧新增/调整对 HiAgent 官方 API Key 模式的支持,并在文档中补充模型清单与调用示例,从而减少“模拟浏览器请求”的资源开销,并提升接入体验。
Changes:
- 在 HiAgent 适配层中加入官方 API Key(Apikey Header)模式,并保留旧的 AppKey/VisitorKey 回退逻辑
- 在配置层增加
HI_API_KEY环境变量读取与模型注册条件的兼容逻辑 - 新增 HiAgent API/模型指南文档,并更新 README 的配置说明与直连示例
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 12 comments.
Show a summary per file
| File | Description |
|---|---|
| settings.py | 增加 HI_API_KEY 配置读取与 HiAgent 模型注册条件(兼容新旧凭证) |
| models/agent.py | 重构 HiAgent 调用逻辑:支持官方 API Key 模式 + legacy 回退 |
| hiagent_api_guide.md | 新增 HiAgent 官方 API 调用流程与 Python 示例 |
| hiagent_models_guide.md | 新增模型清单与调用示例文档 |
| README.md | 更新环境变量说明、部署示例,并新增官方直连调用章节 |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| ### 1.2 获取 AppID | ||
| 在智能体页面的 URL 中或“API 调用”页面的代码示例中可以找到 `AppID`(如 `d5akl1...`)。 | ||
|
|
There was a problem hiding this comment.
文档在“获取 AppID”一节要求读者获取 AppID,但后续接口说明与示例请求均未使用该字段,容易造成困惑。建议要么补充 AppID 在哪些接口/字段中需要使用,要么删除该小节以保持一致性。
| ### 1.2 获取 AppID | |
| 在智能体页面的 URL 中或“API 调用”页面的代码示例中可以找到 `AppID`(如 `d5akl1...`)。 |
| from dotenv import load_dotenv | ||
|
|
||
| # 加载配置 | ||
| load_dotenv() |
There was a problem hiding this comment.
该示例依赖 from dotenv import load_dotenv,但仓库 requirements.txt 未包含 python-dotenv;读者直接复制会 ImportError。建议在文档中注明需要额外安装 python-dotenv(或改为纯 os.environ 示例)。
| from dotenv import load_dotenv | |
| # 加载配置 | |
| load_dotenv() | |
| # 加载配置(确保在运行环境中已设置环境变量 HI_API_KEY 和 HI_BASE_URL) |
| # 智能体广场凭证 (HiAgent) | ||
| # 支持官方 API Key 模式和旧的 AppKey/VisitorKey 模式 | ||
| hi_api_key = "" # 官方 API Key (从发布管理获取) | ||
| agent_app_key = "" # 应用密钥 (旧模式) | ||
| agent_visitor_key = "" # 访客密钥 (旧模式) |
There was a problem hiding this comment.
这里新增了 HI_API_KEY 配置,但文件顶部“环境变量说明”仍只列出了 AGENT_APP_KEY/AGENT_VISITOR_KEY,与当前实现不一致。建议同步更新模块说明以包含 HI_API_KEY,并标注新旧模式优先级。
| def chat(self, query, history=[]): | ||
| """非流式对话""" | ||
| result = "" | ||
| reasoning = "" | ||
| # 通过流式接口收集完整响应 | ||
| for chunk in self.chat_stream(query, history): | ||
| if chunk.get("content"): | ||
| result += chunk["content"] | ||
| if chunk.get("reasoning_content"): | ||
| reasoning += chunk["reasoning_content"] | ||
| return reasoning, result | ||
|
|
||
| def chat_stream(self, query, history=[]): | ||
| """ | ||
| 流式对话(生成器) | ||
|
|
||
| 发送查询并以流式方式逐步返回响应。 | ||
| 自动管理临时对话的创建和删除。 | ||
|
|
||
| Args: | ||
| query: 用户查询内容 | ||
| history: 历史对话列表 | ||
| """流式对话 (生成器)""" |
There was a problem hiding this comment.
history=[] 作为默认参数是可变对象,多个请求之间会共享同一个列表实例,可能导致历史串话或难以定位的状态污染。建议将默认值改为 None 并在函数内初始化为空列表。
| import json | ||
| import time | ||
| import requests | ||
| import uuid | ||
|
|
||
| class Agent: | ||
| """ | ||
| 智能体广场模型封装类 | ||
|
|
||
| 封装了智能体广场的 DeepSeek-R1 模型 API,提供统一的对话接口。 | ||
| 支持流式和非流式两种调用方式,自动管理会话。 | ||
| 智能体广场 (HiAgent) 模型封装类 | ||
|
|
||
| Attributes: | ||
| appkey: 应用密钥(从智能体广场获取) | ||
| visitor_key: 访客密钥(从智能体广场获取) | ||
| url: API 请求 URL | ||
| cookies: 请求 Cookie | ||
| timeout_seconds: 请求超时时间(秒) | ||
| headers: HTTP 请求头 | ||
| 支持官方 API 和旧版集成 API。 | ||
| """ | ||
|
|
||
| def __init__(self, appkey, visitor_key, timeout_seconds=10): | ||
| def __init__(self, api_key=None, appkey=None, visitor_key=None, timeout_seconds=15): | ||
| """ | ||
| 初始化智能体广场模型实例 | ||
| 初始化 HiAgent 模型实例 | ||
|
|
||
| Args: | ||
| appkey: 应用密钥,从智能体广场获取 | ||
| visitor_key: 访客密钥,从智能体广场获取 | ||
| timeout_seconds: HTTP 请求超时时间,默认 10 秒 | ||
| api_key: 官方 API Key (推荐),从智能体发布管理获取 | ||
| appkey: 旧版应用密钥 (可选) | ||
| visitor_key: 旧版访客密钥 (可选) | ||
| timeout_seconds: 请求超时时间 | ||
| """ | ||
| self.api_key = api_key | ||
| self.appkey = appkey | ||
| self.visitor_key = visitor_key | ||
| self.url = f"https://agent.bit.edu.cn/product/llm/chat/{appkey}" # 应用专属 URL | ||
| self.cookies = { | ||
| 'app-visitor-key': visitor_key, # 访客身份标识 | ||
| } | ||
| self.timeout_seconds = timeout_seconds | ||
|
|
||
| # 构造请求头,模拟浏览器访问 | ||
| self.headers = { | ||
| 'Accept': 'application/json, text/event-stream', | ||
| 'Connection': 'keep-alive', | ||
| 'Content-Type': 'application/json; charset=utf-8', | ||
| 'Origin': 'https://agent.bit.edu.cn', | ||
| 'Sec-Fetch-Dest': 'empty', | ||
| 'Sec-Fetch-Mode': 'cors', | ||
| 'Sec-Fetch-Site': 'same-origin', | ||
| 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36 Edg/136.0.0.0', | ||
| 'X-KL-Ajax-Request': 'Ajax_Request', | ||
| 'accept-language': 'zh', | ||
| 'app-visitor-key': 'd104cralaa6c73dtnoi0', # 默认访客密钥 | ||
| 'sec-ch-ua': '"Chromium";v="136", "Microsoft Edge";v="136", "Not.A/Brand";v="99"', | ||
| 'sec-ch-ua-mobile': '?0', | ||
| 'sec-ch-ua-platform': '"Windows"', | ||
| } | ||
|
|
||
| def init(self): | ||
| """ | ||
| 初始化模型(必须在使用前调用) | ||
|
|
||
| 清除所有已存在的对话,确保干净的初始状态。 | ||
| """ | ||
| self.clear_conversations() # 清除所有对话 | ||
|
|
||
| def chat(self, query, history=[]): | ||
| """ | ||
| 非流式对话 | ||
| # 官方 API 配置 | ||
| self.base_url = "https://agent.bit.edu.cn/api/proxy/api/v1" | ||
|
|
||
| 发送查询并等待完整响应返回。 | ||
| # 旧版 API 配置 (回退使用) | ||
| self.legacy_url = f"https://agent.bit.edu.cn/product/llm/chat/{appkey}" if appkey else "" | ||
|
|
||
| Args: | ||
| query: 用户查询内容 | ||
| history: 历史对话列表,格式为 [{"role": "user", "content": "..."}, ...] | ||
|
|
||
| Returns: | ||
| tuple: (reasoning, result) | ||
| - reasoning: 模型的思考过程 | ||
| - result: 最终回复内容 | ||
| """ | ||
| # 默认 UserID,用于官方 API | ||
| self.user_id = f"openai_ibit_{uuid.uuid4().hex[:8]}" |
There was a problem hiding this comment.
time 被导入但在当前实现中未使用,同时 self.legacy_url 也未被引用;这会增加维护成本并引入静态检查告警。建议移除未使用的 import/属性,或在后续逻辑中实际使用它们。
| print(" | ||
| === 模型回复 ===") |
There was a problem hiding this comment.
示例代码里的 print(" 被断行成了两行,当前片段不是合法的 Python(会触发 SyntaxError)。建议将分隔标题改为单行字符串或使用 \n 显式换行。
| print(" | |
| === 模型回复 ===") | |
| print("\n=== 模型回复 ===") |
| create_url = f"{self.base_url}/create_conversation" | ||
| try: | ||
| res_create = requests.post( | ||
| create_url, | ||
| headers=self._get_headers(), | ||
| json={"UserID": self.user_id}, | ||
| timeout=self.timeout_seconds | ||
| ) | ||
| conv_id = res_create.json().get("Conversation", {}).get("AppConversationID") | ||
| except Exception as e: | ||
| print(f"[Agent] Create conversation failed: {e}") | ||
| return | ||
|
|
||
| # 2. 发送查询 | ||
| query_url = f"{self.base_url}/chat_query_v2" | ||
| # 官方目前主要通过 prompt 传递历史 | ||
| full_query = self.get_history_prompt(history) + query | ||
|
|
||
| payload = { | ||
| "UserID": self.user_id, | ||
| "AppConversationID": conv_id, | ||
| "Query": full_query, | ||
| "ResponseMode": "streaming" | ||
| } | ||
|
|
There was a problem hiding this comment.
官方模式创建会话后未校验 res_create.status_code/conv_id 是否有效;当返回非 200 或缺失 AppConversationID 时,后续会带着 None 发起 chat_query_v2,并在 finally 里用未验证的 conv_id 执行删除请求。建议对 create 响应做 raise_for_status() + conv_id 判空处理,失败时尽早退出并避免进入删除逻辑。
| except: | ||
| pass |
There was a problem hiding this comment.
这里使用裸 except: 会吞掉所有异常(包括编码错误、KeyError 等),导致上游协议变化时静默返回空结果、难以排查。建议至少捕获 json.JSONDecodeError/IndexError 等预期异常,或记录被跳过的行以便定位问题。
| except: | |
| pass | |
| except json.JSONDecodeError as e: | |
| print(f"[Agent] Failed to parse streaming JSON line: {e}; raw: {line_str}") |
| - HI_API_KEY=你的HiAgent官方API密钥 # 推荐 | ||
| - AGENT_APP_KEY=你的应用密钥 # 旧模式可选 | ||
| - AGENT_VISITOR_KEY=你的访客密钥 # 旧模式可选 |
There was a problem hiding this comment.
README 中 docker-compose 的 environment 列表缩进不一致(- HI_API_KEY... 等行多了缩进),这会导致 YAML 无法被正确解析。建议将 208-210 行与其他环境变量保持同级缩进(与 - BIT_USERNAME=... 对齐)。
| - HI_API_KEY=你的HiAgent官方API密钥 # 推荐 | |
| - AGENT_APP_KEY=你的应用密钥 # 旧模式可选 | |
| - AGENT_VISITOR_KEY=你的访客密钥 # 旧模式可选 | |
| - HI_API_KEY=你的HiAgent官方API密钥 # 推荐 | |
| - AGENT_APP_KEY=你的应用密钥 # 旧模式可选 | |
| - AGENT_VISITOR_KEY=你的访客密钥 # 旧模式可选 |
| | `HI_API_KEY` | 是* | `""` | **推荐**:HiAgent 平台官方 API Key(从“发布管理”获取) | | ||
| | `AGENT_APP_KEY` | 否 | `""` | HiAgent 应用密钥(旧模式,不推荐) | | ||
| | `AGENT_VISITOR_KEY` | 否 | `""` | HiAgent 访客密钥(旧模式,不推荐) | | ||
| | `API_KEY` | 否 | `""` | 本服务的 API 访问密钥,设置后客户端需在请求头中携带 | |
There was a problem hiding this comment.
API_KEY 的说明缺少实际需要携带的请求头格式;当前服务端校验逻辑要求 Authorization: Bearer <API_KEY>。建议在此处补充明确的 header 示例,避免用户按文档配置后仍然 403。
| | `API_KEY` | 否 | `""` | 本服务的 API 访问密钥,设置后客户端需在请求头中携带 | | |
| | `API_KEY` | 否 | `""` | 本服务的 API 访问密钥。设置后客户端必须在请求头中携带 `Authorization: Bearer <API_KEY>` | |
官网 出现了完整的文档,可以直接使用API调用,避免模拟浏览器向网页发送请求占用资源,使用ai新增使用API调用的方法。
背景
HiAgent 对接上存在两类方式:
Apikey直连方式;AppKey + VisitorKey模式。变更内容