[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-77431":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":8,"htmlUrl":8,"language":9,"languages":8,"totalLinesOfCode":8,"stars":10,"forks":11,"watchers":12,"openIssues":13,"contributorsCount":13,"subscribersCount":13,"size":13,"stars1d":13,"stars7d":13,"stars30d":14,"stars90d":13,"forks30d":13,"starsTrendScore":13,"compositeScore":15,"rankGlobal":8,"rankLanguage":8,"license":8,"archived":16,"fork":16,"defaultBranch":17,"hasWiki":18,"hasPages":16,"topics":19,"createdAt":8,"pushedAt":8,"updatedAt":20,"readmeContent":21,"aiSummary":22,"trendingCount":13,"starSnapshotCount":13,"syncStatus":23,"lastSyncTime":24,"discoverSource":25},77431,"Simple-ReAct-Agent","rulyone\u002FSimple-ReAct-Agent","rulyone",null,"Python",115,10,35,0,42,41.32,false,"main",true,[],"2026-06-12 04:01:21","# Local ReAct Agent\n\nA minimal, \"hand-built\" ReAct agent that runs entirely on your computer using\n[Ollama](https:\u002F\u002Follama.com) + Llama 3.2 3B. Four short Python files, no\nSDK abstractions over the loop — every Action is parsed from text and\ndispatched manually.\n\nNo API key. No paid subscription. ~3 GB disk for the model.\n\n## Pseudo Code\n\n![Pseudo Code](pseudo_code.png)\n\n## What this teaches\n\n- **Chat API roles** — every message is tagged `system` \u002F `user` \u002F `assistant`.\n  Tool observations are injected as `user` messages with an `Observation:`\n  prefix (the original 2022 ReAct paper convention).\n- **Stop sequences** — Ollama's `stop` parameter halts generation before the\n  model writes `Observation:`, so each assistant message contains exactly\n  one Action. A regex catches any stragglers client-side.\n- **Prompt-as-history** — the LLM is stateless. The full `messages` list is\n  re-sent every turn. That's literally the \"context window\" filling up.\n- **Inner vs outer loop** — the outer loop is multi-turn conversation\n  (`repl.py`). The inner loop is the ReAct iteration within one user turn\n  (`react.py`). They're two distinct loops doing different jobs.\n- **Tool dispatch** — `tools.TOOLS` is a single dict mapping name → function.\n  The system prompt is generated from it. Adding a tool is one entry.\n- **No SDK tool-use** — the agent loop is hand-built on top of a plain chat\n  API. Every Action is parsed from text and dispatched manually.\n\n## Files\n\n| File | Lines | What it does |\n|---|---|---|\n| `llm.py` | ~40 | One pure function: `chat(messages, stop)` → text |\n| `tools.py` | ~95 | `calculate` (AST eval), `web_search` (DuckDuckGo, no key), `dispatch` |\n| `react.py` | ~95 | `SYSTEM_PROMPT`, `parse_action`, `agent_turn` |\n| `repl.py` | ~55 | Multi-turn REPL with `\u002Fclear`\u002F`\u002Fhistory` commands |\n| `requirements.txt` | 2 | `httpx`, `ddgs` |\n\n## Prereqs\n\n- Python 3.10+\n- Linux \u002F macOS with [Homebrew](https:\u002F\u002Fbrew.sh) (other installers work too)\n- ~3 GB free disk (Llama 3.2 3B is ~2 GB)\n\n## One-time setup\n\n```bash\nbrew install ollama\nbrew services start ollama          # daemon on localhost:11434\nollama pull llama3.2:3b             # ~2 GB, one-time download\n```\n\n## Per-session setup\n\n```bash\ncd \u002Fpath\u002Fto\u002Fagent-loop\npython3 -m venv .venv\nsource .venv\u002Fbin\u002Factivate\npip install -r requirements.txt\n```\n\n## Run\n\n```bash\npython -m repl\n```\n\n### REPL commands\n\nTyped at the `user>` prompt. Handled by `repl.py`, never sent to the model.\n\n| Command | Effect |\n|---|---|\n| `quit` \u002F `exit` \u002F Ctrl-D | Leave the REPL |\n| `\u002Fclear` | Drop the conversation history (keeps the system prompt) |\n| `\u002Fhistory` | Dump every message in the current context, indexed and role-tagged |\n\nAnything else is treated as a user question and triggers one `agent_turn`.\n\nSample session:\n\n```\nuser> add 100 to the year of the last presidential election in Chile               \n  [step 1] thought: I need to find the year of the last presidential election in Chile.\n  [step 1] action:  web_search[last presidential election in Chile]\n  [step 1] observ:  - 2025 Chilean general election - Wikipedia: General elections were held in Chile on 16 November 2025. Voters went to th...\n  [step 2] thought: The last presidential election in Chile was in 2025, so I need to add 100 to that year.\n  [step 2] action:  calculate[2025 + 100]\n  [step 2] observ:  2125\n  [step 3] thought: The result of adding 100 to the year of the last presidential election in Chile is indeed 2125.\n  [step 3] action:  finish[2125]\n\nassistant> 2125\n\nuser> divide that by 5\n  [step 1] thought: I need to divide 2125 by 5 to get the final answer.\n  [step 1] action:  calculate[2125 \u002F 5]\n  [step 1] observ:  425.0\n  [step 2] thought: The result of dividing 2125 by 5 is indeed 425.0, which makes sense as it's a simple division problem.\n  [step 2] action:  finish[425.0]\n\nassistant> 425.0\n\nuser> \u002Fclear\n(history cleared)\n```\n\n## Customize\n\n- **Add a tool** — add one entry to `tools.TOOLS`. The system prompt picks\n  it up automatically via `docs()`.\n- **Swap the model** — change `MODEL` in `llm.py`. Tiny models that work (sometimes):\n  `llama3.2:1b` (faster, less reliable format), `qwen2.5:3b`, `qwen2.5:1.5b`.\n- **More steps** — raise `max_steps` in `agent_turn` (default 8).\n- **Less deterministic** — raise `temperature` in the `chat` call (default 0).\n\n## Troubleshooting\n\n- `httpx.ConnectError`: Ollama isn't running. `brew services start ollama`.\n- First turn is slow (~10 s): model loading into memory. Subsequent turns\n  use the warm cache.\n- Model emits text instead of `Action: ...`: format drift. The loop catches\n  it and prints `(no action - using reply as final)`. Llama 3.2 3B is\n  reliable; smaller models drift more.\n- Tool raises an exception: caught and reported as\n  `Observation: Error from \u003Ctool>: \u003Cmessage>` so the model can react.\n- Answers are not logical: we are not using a Frontier model here.\n","这是一个基于本地运行的简易ReAct代理项目，使用Ollama和Llama 3.2 3B模型，在用户的计算机上完全执行。项目由四个简短的Python文件组成，不依赖于任何SDK抽象层，所有动作都是从文本中解析并手动分发的。其核心功能包括聊天API角色定义、停止序列处理、无状态LLM交互以及工具调度等，强调了手写实现的重要性。适合需要在本地环境中构建轻量级对话系统的开发者，无需API密钥或付费订阅，仅需约3GB磁盘空间即可运行。",2,"2026-06-11 03:55:27","CREATED_QUERY"]